From 8ad8d0e88cea8e2f410a0bbe7facf2b43792b020 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Wed, 12 Sep 2018 15:26:27 -0400 Subject: [PATCH] signal names on top, remove clk/reset from video, wave numbers at high zoom --- lib/w2ui-1.5.rc1.css | 3247 +++++++ lib/w2ui-1.5.rc1.js | 18953 +++++++++++++++++++++++++++++++++++++ lib/w2ui-1.5.rc1.min.css | 2 + lib/w2ui-1.5.rc1.min.js | 14 + src/platform/verilog.ts | 6 +- src/waveform.ts | 25 +- 6 files changed, 22239 insertions(+), 8 deletions(-) create mode 100644 lib/w2ui-1.5.rc1.css create mode 100644 lib/w2ui-1.5.rc1.js create mode 100644 lib/w2ui-1.5.rc1.min.css create mode 100644 lib/w2ui-1.5.rc1.min.js diff --git a/lib/w2ui-1.5.rc1.css b/lib/w2ui-1.5.rc1.css new file mode 100644 index 00000000..1c356eee --- /dev/null +++ b/lib/w2ui-1.5.rc1.css @@ -0,0 +1,3247 @@ +/* w2ui 1.5.rc1 (nightly) (c) http://w2ui.com, vitmalina@gmail.com */ +@font-face { + font-family: "w2ui-font"; + src: url("data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAA2QAA4AAAAAFswAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABRAAAAEMAAABWQLxMu2NtYXAAAAGIAAAAOgAAAUriGxC2Y3Z0IAAAAcQAAAAUAAAAIv+WA5hmcGdtAAAB2AAABacAAAuX2BTb8Gdhc3AAAAeAAAAACAAAAAgAAAAQZ2x5ZgAAB4gAAANfAAAEmA0SrIBoZWFkAAAK6AAAADIAAAA2BV3r6GhoZWEAAAscAAAAIAAAACQD8wHJaG10eAAACzwAAAAYAAAAKBLdAABsb2NhAAALVAAAABYAAAAWBaAEAm1heHAAAAtsAAAAIAAAACABBgv1bmFtZQAAC4wAAAEtAAACIsTQ/zJwb3N0AAAMvAAAAFQAAABxEzKM+HByZXAAAA0QAAAAfQAAAIqMht7EeJxjYGR8zDiBgZWBg9GFMY2BgcEdSn9lkGRoYWBgYmBlZsAKAtJcUxgcPjJ+5GQ88P8Agx7jAQZHoDAjSA4A1EQL+wB4nGNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZgYGD5y/v8PUvCREUTzM0DVAwEjG8OIBwB4FgbAAAB4nGNgwAA8EMh44P9+EAYAFmAFL3icrVb5c9NGFJZ8JE5CjpKDFvVYsXGa2iuTUggGTAiSZRfcw7laCUorxU56H9Ayw9/gv+bJtDP0N/60fm9lm0CSdoZpJqP37e6nffeTyVCCjL3AD4VoPTNmtlo0tnMvoMsWrYbRoejtBZQpxn8XjILR6ch9y7bJCMnwZL1vmIYXuQ6ZikR06FBGia6g523Krdzrr5qTnt/xt+8HtrStXiCo3Q5s2gwtQVVG1TAUSUqKu7SKrcFK0BqfrzHzeTsQMKIXC5psBxF2BJ9NMlpntB5ZURiGFpnlMJRktIODMHQoqwTuyRVjGJT32gHlpUtj0oX5IZmRQzklYZfoJvl9V/BJqpyfOPc7lC3Z2PdET/Rwd7KWL8KtrSBqW/F2GMgQp5s7AY4sdmqg2aG8onGv3DcyaWjGsJSuRIilG1Nm/5DMDu6nfMmhcSXYyCmv8yxn7Au+gTajkClRXRtZUP3xKcPz3ZI9CvaEejn4k+ktZhkmePA4En5PxpwIHSnD4miSsGDk0ErKFmVcT1VMnfI6LeMtw3rh2tGXzijtUH9qMusHtiXtsGQ7NK2STManblx3aEaBKASd8e7y6wDSDWmaV9tYTWPl0CyumdMhEYhAB3ppxotELxI0g6A5NKdau0GS69bDZZo+kE8cekO1toLWTrpp2dif1/tnVWLMentBMjuL/MUuzZa5SFG6bnKGH9N4kLmETGSL7SDh4MFbt4f0stqSLfHaEFvpOb+C2uedEJ40YX8Tuy+n6pQEJoYxLxEtj4yNvmmaOlfzykiMjL8b0Kx0hU9TKMpJKI5cEUH9X3NzpjFjuG4vSs6Olelx2bqAMC3At/myQ4sqMVkuIc4sz6kky/JNleRYvqWSPMvzKhljaalknOXbKimwfEclEyw/UKJC5gOHSho8dKiswSOH3lUGTZdfw8b3YOO7uFvARpY2bGR5ATaylLCR5TJsZFmEjSxXYCPL92Ejy1XYyFIpUdOl5iionYuExyZ4Oh1oH8X1VlHklMlBJ11EETfFKZmQcVXyGPtXBkrJobVReswlulhK8uaiH2AMsYMfHo3M8eNLSlzR9n4EnukfV4IOO1E57xtLfxr8V9+Q1eSSuQiPLsN/GHyyvSjsuOrQFVU5V3No/b+oKMIO6FeREmOpKCqiyc2LUN7p9ZqyiW4PMNYxFtHR66a5uAD9VUyZJTQI/jWFJrzyQa8ihaj1cNe1F8eikt5BOdwJlqCI+31zK3iaEVlhPc2sZM+HLs/AAqap1GzZQPd5r7ZSxHMoHfYZL+pKynpxF8cZL7aAI55Br74TwyQMZtlADiU0NOAXhNaC+05QItNpl0ODI/Z5FFT+2K24kT0qaiPwbKdT7oUupPw6x0BgJ78yiIGsITQ39DYV0DxCNGSTlXG2ajpk7MAgosZuUBE1fBvZ4sGmYFuGIR8rYnXn6Nc3TdRJFTzIjOQyvjmwwBumJuLP86suDlO5oaSocNQaGMy1sJJUzAU04K3Rdvvo9ubL7BM5txVVyyde6iq6Vu5BMRcLrD3OQVoqVAHVG1XYMLpcXBKlXkGTpNfVMTQww1+jFJv/V/Wx+TxfahIj5Ei+7XBgo8/BGPrfYP9tOQjAwI+Ry024vJg2J77u6MP5Cl1GL358yv4dzFxzYZ6uAN9VdBWixVHzEVfRwKdsGKdPFJcjtQA/VX3MGYDPAEwGn6u+qXfaAHpnizk+wDZzGOwwh8EucxjsMec2wBfMYfAlcxgEzGEQMscDuMccBveZw+Ar5jB4wJwGwNfMYfANcxhEzGEQM8cF2GcOgw5zGHSZw+BA0fVRmA95QRtA32p0C+g7XU9YbGLxvaIbI/YPvNDsHzVi9k8aMfVnRbUR9RdeaOqvGjH1N42Y+lDRzRH1ES809XeNmPqHRkx9rJ5O5DLDH09umQoHlF1uPxl+U5x/ACtxTWMAAAEAAf//AA94nJVTPWzbRhj9vjuKP5JMSTFFWqL1Y1EkIxBxY8kUIxu1uBRp7AQWMtgOKAEOMqRGY8BwAQdBF6MIuhUw2qFLEXQo0KEyELRbl7pLhwDdW3TJ1q3w0qGL1Y9i1HYtgXt399073LvHd4AAk0sGeAopEL8TAG96KLmSgfjy8mhwgSGeJj0AcOL+hb/hCxpJkIFSqAuM9sJxijPEg0L85UWx7M13CtastaLomygaRxG+uBriV0mjTfThc/wEmlANzbqhpgRguMmRATtGWj7QFjVTEBc8NHQtl4DYeAulGJzVProxdNs1DLptAweeooxGiuIpJXk0VErKv3NlOJJLCj73CJMlWR6NZDlZIj5Rh0NFiSUJdMcLutMF5KAENqzA51svlcFeGACkMQ3vAeMKZ8oR3SAlYOohCCJyJvCHkE5LUQYlaW4ri4oiRyDLqnzXDG8lO/Ho/259EJZdxyzf8JwVd2WpVrZNO3Z43m/PiaY3v9pdx7ZeQU30sOH4huV3fGrFDldRqqKxgcEy8mV0aUBTFV+r6XxancL+ab2+Xw8Pzzg/O0xw74Sxk70p4vU3NDX9C9FOcf8f1uHZVWdGIwRGfv2Kv+PX5Nw8aCEFQJU5E+E2mXlgolj0+szNIcnoM0viduDn8Ke1V5VXt9OL+o3e+c75DtbHY+vjCtW+1BfTH1rj8dVrKp/34ohMc/IZfgEWtEIHBC4cUxE/SCHFke9SxyFiSJHctjq21bHi/NnF2JRi4szbaMUQ2+XPPOu0dfw0n3mazwTZ/NNMPh5mg0w8/IMqJ9l8Pnsyq8SLkGiZ/Inf4vfQgpVwuUmHtq7T0WzTRv5u/DxI0yNAxnAXEFlEgWbbrucuTWPsWA2VaVXWaXeDDayhrkkqSVtmqxtU042AdEkYtG5VfMcwHL+ytF5kMnc4q+3c9Aa9RqM38Fr3Ku8IP2PgGq6/7rtGtcyRu4yMbVlrg93BmlWrbMsP3l8gvWwymfxAD/NimuRe2L2GTMBNoPSlQDgSkV4cF9gjSKUwIsFzW8C5yu+a5SRsetO+JpFy23WkDfTpFybBIv1iDavYdez/pAsvn2kFfYE9uX//CSNs9stYeKw2TXb1Y/cO4p3uFLOPC1juNxMO4YJe0J7lmNn8aMYghL8BN5m3wQB4nGNgZGBgAOKnn6qi4vltvjJwMzGAwCV52TII3fvt////+5kYGQ8AuRwMYGkAX08M3AAAeJxjYGRgYDzw/wCDHhMDA8P/f0xMDEARFMAFAHuABL54nGNiYGBggmLGyQg2jM+4HcIGAByDAe8AAAAAABYAPACIAIgBIAFQAZYB7gJMAAAAAQAAAAoAMgAEAAAAAAACABoAKgB3AAAAZguXAAAAAHicbY9NbsIwEIVfIFAVpAq1UqXurC66qQg/CxYcAPYs2IfgBFASR45B4gI9Qc/QM/QEXfYMPUpfwiiLFlsef/PmjX8ADPAFD9XwcFvHarRww+zCbdJA2Cc/CXfQx7Nwl/pQuIdXzIT7eEDIEzy/Ou0eTriFO7wJt6m/C/vkD+EOHvEp3KX+LdzDGj/Cfbx4s31k8mFscrfSyTENbZM3sNa23JtcTYJxoy11rm3o9FZtzqo8JVPnYhVbk6kFqzpNjSqsOejIBTvnivloFIseRCbDHhEMcv46rneHFTQSHJHyx/ZK/b+yZodFyUqVK0wQYHzFt6Qvr70hM40tvRucGUuceOeUqqNbcVn2ZKSF9Gq+JyUrFHXtQCWiHmBXdxWYY8QZ//EH9SuyX24OYHIAAAB4nG3BSw6AIAwFwD6l+LmlaWogIhAKC2/vwq0zNNGH6d9OhAkzHBgeC1Zs2FmCyrVISePOxtKKGetd++NiPouvmiUmV9Mw37Tq0b3p0SQQvYZKFLt4nGPw3sFwIihiIyNjX+QGxp0cDBwMyQUbGdicNjEwMmiBGJu5mRg5ICx+BjCL3WkXMwNQmhPI5nDaxeAAYTMzuGxUYewIjNjg0BGxkTnFZaMaiLeLo4GBkcWhIzkkAqQkEgg28zIx8mjtYPzfuoGldyMTUB9rigsAZa0kmwAAAA==") format("woff"); + font-weight: normal; + font-style: normal; +} +[class^="w2ui-icon-"]:before, +[class*=" w2ui-icon-"]:before { + font-family: "w2ui-font"; + display: inline-block; + vertical-align: middle; + line-height: 1; + font-weight: normal; + font-style: normal; + speak: none; + text-decoration: inherit; + text-transform: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* Icons */ +.w2ui-icon-check:before { + content: "\f101"; +} +.w2ui-icon-columns:before { + content: "\f102"; +} +.w2ui-icon-cross:before { + content: "\f103"; +} +.w2ui-icon-empty:before { + content: "\f104"; +} +.w2ui-icon-info:before { + content: "\f105"; +} +.w2ui-icon-pencil:before { + content: "\f106"; +} +.w2ui-icon-plus:before { + content: "\f107"; +} +.w2ui-icon-reload:before { + content: "\f108"; +} +.w2ui-icon-search:before { + content: "\f109"; +} +/************************************************* +* --- Reset (used for all w2ui widgets) +* --- The reset is needed to coexist with other CSS +* --- on the same page (for example bootstrap) +*/ +.w2ui-reset { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; + font-family: Verdana, Arial, sans-serif; + font-size: 11px; +} +.w2ui-reset * { + color: default; + line-height: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; + margin: 0px; + padding: 0px; +} +.w2ui-reset table { + max-width: none; + background-color: transparent; + border-collapse: separate; + border-spacing: 0; + border: none; +} +.w2ui-reset table tr th, +.w2ui-reset table tr td { + font-family: Verdana, Arial, sans-serif; + font-size: 11px; +} +.w2ui-reset input:not([type=button]):not([type=submit]):not([type=checkbox]):not([type=radio]), +.w2ui-reset select, +.w2ui-reset textarea { + display: inline-block; + width: auto; + height: auto; + vertical-align: baseline; + padding: 4px; + margin: 0; + font-size: 11px; +} +.w2ui-reset select { + padding: 1px; + height: 23px; + font-size: 11px; +} +.w2ui-centered { + position: absolute; + left: 0px; + right: 0px; + top: 50%; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + max-height: 100%; + margin: 0px; + padding: 0px 10px; + text-align: center; +} +.w2ui-disabled, +.w2ui-readonly { + background-color: #f1f1f1 !important; + color: #777 !important; +} +.w2ui-message { + font-size: 12px; + position: absolute; + z-index: 250; + background-color: #f9f9f9; + border: 1px solid #999999; + box-shadow: 0px 0px 15px #aaaaaa; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; + border-top: 0px; + border-radius: 0px 0px 6px 6px; + overflow: auto; +} +.w2ui-message .w2ui-message-body { + position: absolute; + top: 0px; + bottom: 45px; + left: 0px; + right: 0px; + overflow: auto; + line-height: 1.5; + font-size: 14px; +} +.w2ui-message .w2ui-message-body .w2ui-centered { + line-height: 1.5; +} +.w2ui-message .w2ui-message-buttons { + position: absolute; + height: 45px; + bottom: 0px; + left: 0px; + right: 0px; + border-top: 1px solid #e5e5e5; + text-align: center; + padding: 8px; +} +/************************************************* +* ---- Input Controls ---- +*/ +input:not([type=button]):not([type=submit]).w2ui-input, +textarea.w2ui-input { + padding: 4px; + border: 1px solid #cacaca; + border-radius: 3px; + color: #000000; + background-color: #ffffff; + line-height: normal; +} +input:not([type=button]):not([type=submit]).w2ui-input:focus, +textarea.w2ui-input:focus { + outline-color: #72b2ff; +} +input:not([type=button]):not([type=submit]).w2ui-input:disabled, +textarea.w2ui-input:disabled, +input:not([type=button]):not([type=submit]).w2ui-input[readonly], +textarea.w2ui-input[readonly] { + background-color: #f1f1f1; + color: #777; +} +/* IE9-11 specific classes */ +/* needs doblue :: */ +input.w2ui-input::-ms-clear { + display: none; +} +input.w2ui-input:-ms-input-placeholder { + color: #aaa !important; +} +select.w2ui-input { + color: #000000; + padding: 0px 15px 0px 7px; + line-height: 1.8; + border-radius: 3px; + border: 1px solid #cacaca; + -webkit-appearance: none; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAALCAQAAACnzwd+AAAAcklEQVR4AcXMsQFBQQDG4P9tAgC0gJYRQJZgKQMwCqCku6vVAAAA+NJHP4KHOk0aV2pRw61n4BBmyOxKQ8I4ehZeuhd3HTx6DQEGZ7sBfr2OOOOj3Yi43kMKs9sZknofOexqZ8npMygwWZTX51CipP+YA1OiZJbYYg9lAAAAAElFTkSuQmCC'), -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-size: 17px 6px, 100% 100%; + background-position: right center, left top; + background-repeat: no-repeat, no-repeat; +} +.w2ui-icon-expand:before { + position: relative; + top: 1px; + left: 1px; + content: ' '; + width: 6px; + height: 6px; + border: 2px solid rgba(150, 150, 150, 0.8); + border-bottom: 0; + border-left: 0; + transform: rotateZ(45deg); +} +.w2ui-icon-collapse:before { + position: relative; + top: -1px; + left: 3px; + content: ' '; + width: 6px; + height: 6px; + border: 2px solid rgba(150, 150, 150, 0.8); + border-bottom: 0; + border-left: 0; + transform: rotateZ(135deg); +} +/* On/Off switch */ +input[type="checkbox"].w2ui-toggle { + position: absolute; + opacity: 0; + width: 46px; + height: 22px; + padding: 0px; + margin: 0px; + margin-left: 2px; +} +/* Track */ +input[type="checkbox"].w2ui-toggle + div { + display: inline-block; + width: 46px; + height: 22px; + border: 1px solid #bbb; + border-radius: 30px; + background-color: #eee; + -webkit-transition-duration: .3s; + -webkit-transition-property: background-color, box-shadow; + -moz-transition-duration: .3s; + -moz-transition-property: background-color, box-shadow; + box-shadow: inset 0 0 0 0px rgba(0, 0, 0, 0.4); + margin-left: 2px; +} +input[type="checkbox"].w2ui-toggle:disabled + div { + opacity: 0.3; +} +/* Knob */ +input[type="checkbox"].w2ui-toggle + div > div { + float: left; + width: 22px; + height: 22px; + border-radius: inherit; + background: #f5f5f5; + -webkit-transition-duration: 0.3s; + -webkit-transition-property: transform, background-color, box-shadow; + -moz-transition-duration: 0.3s; + -moz-transition-property: transform, background-color; + box-shadow: 0px 0px 1px #323232, 0 0 0 1px rgba(200, 200, 200, 0.6); + pointer-events: none; + margin-top: -1px; + margin-left: -1px; +} +/* Default Green */ +input[type="checkbox"].w2ui-toggle:checked + div { + border: 1px solid #00a23f; + box-shadow: inset 0 0 0 12px #54B350; +} +input[type="checkbox"].w2ui-toggle:checked + div > div { + -webkit-transform: translate3d(24px, 0, 0); + -moz-transform: translate3d(24px, 0, 0); + background-color: #ffffff; + box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3), 0 0 0 1px #00a23f; +} +/* Blue */ +input[type="checkbox"].w2ui-toggle.blue:checked + div { + border: 1px solid #206FAD; + box-shadow: inset 0 0 0 12px #35A6EB; +} +input[type="checkbox"].w2ui-toggle.blue:checked + div > div { + box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3), 0px 0px 0 1px #206fad; +} +input[type=checkbox].w2ui-toggle:focus { + outline: none; +} +/************************************************* +* ---- Overlay and Bubble ---- +*/ +.w2ui-overlay { + position: absolute; + margin-top: 4px; + margin-left: -17px; + display: none; + z-index: 1300; + color: inherit; + background-color: #fbfbfb; + border-color: #fbfbfb; + box-shadow: 0px 2px 10px #999999; + border-radius: 4px; + text-align: left; +} +.w2ui-overlay > div { + border-radius: 4px; + position: relative; + border: 3px solid #777777; +} +.w2ui-overlay table td { + color: inherit; +} +.w2ui-overlay:before { + content: ""; + position: absolute; + border-color: inherit; +} +.w2ui-overlay:after { + content: ""; + position: absolute; + border-color: inherit; + bottom: 100%; + left: 4px; +} +.w2ui-overlay.top-arrow:before { + border-bottom: 12px solid #6f6f6f; + border-right: 12px solid transparent; + border-left: 12px solid transparent; + bottom: 100%; + margin-bottom: -3px; +} +.w2ui-overlay.top-arrow:after { + border-bottom: 8px solid #000000; + border-bottom-color: inherit; + border-right: 8px solid transparent; + border-left: 8px solid transparent; + bottom: 100%; + margin-bottom: -3px; +} +.w2ui-overlay.bottom-arrow:before { + border-top: 12px solid #6f6f6f; + border-right: 12px solid transparent; + border-left: 12px solid transparent; + top: 100%; + margin-top: -3px; +} +.w2ui-overlay.bottom-arrow:after { + border-top: 8px solid #000000; + border-top-color: inherit; + border-right: 8px solid transparent; + border-left: 8px solid transparent; + top: 100%; + margin-top: -3px; +} +.w2ui-overlay.w2ui-overlay-popup { + z-index: 1700; +} +.w2ui-overlay .w2ui-grid-searches { + border-top: 3px solid #777777 !important; +} +.w2ui-overlay .no-color { + border: 1px solid #eee; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABlBMVEX/////TgCFoIUYAAAAGUlEQVR42uXHIQEAAACDsNO/NJ4Kn9uC8wsJkAARUrXAjwAAAABJRU5ErkJggg=='); + background-size: 15px 15px; +} +.w2ui-tag { + position: absolute; + z-index: 1300; + opacity: 0; + -webkit-transition: opacity 0.3s; + -moz-transition: opacity 0.3s; + -ms-transition: opacity 0.3s; + -o-transition: opacity 0.3s; + transition: opacity 0.3s; +} +.w2ui-tag .w2ui-tag-body { + box-sizing: border-box; + display: inline-block; + position: absolute; + border-radius: 3px; + padding: 6px 10px; + margin-left: 10px; + margin-top: 0px; + background-color: rgba(60, 60, 60, 0.9); + color: #ffffff !important; + font-size: 11px; + font-family: verdana; + text-shadow: 1px 1px 3px #000; + line-height: 1.4; + letter-spacing: 0.1px; +} +.w2ui-tag .w2ui-tag-body.w2ui-tag-right:before { + content: ""; + position: absolute; + width: 0; + height: 0; + border-top: 6px solid transparent; + border-right: 6px solid rgba(60, 60, 60, 0.9); + border-bottom: 6px solid transparent; + margin: 0px 0 0 -16px; +} +.w2ui-tag .w2ui-tag-body.w2ui-tag-left:after { + content: ""; + position: absolute; + top: 5px; + width: 0; + height: 0; + border-top: 6px solid transparent; + border-left: 6px solid rgba(60, 60, 60, 0.9); + border-bottom: 6px solid transparent; + margin: 0px 0 0 10px; +} +.w2ui-tag .w2ui-tag-body.w2ui-tag-bottom:before { + content: ""; + position: absolute; + width: 0; + height: 0; + border-right: 6px solid transparent; + border-left: 6px solid transparent; + border-bottom: 6px solid rgba(60, 60, 60, 0.9); + margin: -12px 0 0 2px; +} +.w2ui-tag .w2ui-tag-body.w2ui-tag-top:after { + content: ""; + position: absolute; + left: 12px; + bottom: -6px; + width: 0; + height: 0; + border-right: 6px solid transparent; + border-left: 6px solid transparent; + border-top: 6px solid rgba(60, 60, 60, 0.9); +} +.w2ui-tag.w2ui-tag-popup { + z-index: 1700; +} +/* +* Drop down menu +*/ +.w2ui-overlay table.w2ui-drop-menu { + width: 100%; + color: #000000; + background-color: #ffffff; + padding: 5px 0px; + cursor: default; +} +.w2ui-overlay table.w2ui-drop-menu td { + white-space: nowrap; +} +.w2ui-overlay table.w2ui-drop-menu .w2ui-item-even { + color: inherit; + background-color: #ffffff; +} +.w2ui-overlay table.w2ui-drop-menu .w2ui-item-odd { + color: inherit; + background-color: #f3f6fa; +} +.w2ui-overlay table.w2ui-drop-menu .w2ui-item-group { + color: #444; + font-weight: bold; + background-color: #ECEDF0; + border-bottom: 1px solid #D3D2D4; +} +.w2ui-overlay table.w2ui-drop-menu td.menu-icon { + padding: 3px 0px 4px 6px; + width: 20px; +} +.w2ui-overlay table.w2ui-drop-menu td.menu-icon > span { + height: 20px; + width: 18px; +} +.w2ui-overlay table.w2ui-drop-menu td.menu-text { + padding: 8px 10px 8px 5px; + width: auto; +} +.w2ui-overlay table.w2ui-drop-menu td.menu-count { + text-align: right; +} +.w2ui-overlay table.w2ui-drop-menu td.menu-count > span { + border: 1px solid #f6fcf4; + border-radius: 20px; + width: auto; + height: 18px; + padding: 2px 7px; + margin: 3px 5px 0px 5px; + background-color: #f2f8f0; + color: #666666; + box-shadow: 0px 0px 2px #474545; + text-shadow: 1px 1px 0px #ffffff; +} +.w2ui-overlay table.w2ui-drop-menu td.menu-count > span.hotkey { + border: none; + border-radius: 0px; + background-color: transparent !important; + color: #888; + box-shadow: none; + text-shadow: none; +} +.w2ui-overlay table.w2ui-drop-menu tr:hover { + color: inherit; + background-color: #e6f0ff; +} +.w2ui-overlay table.w2ui-drop-menu tr.w2ui-selected { + background-color: #b6d5fb; +} +.w2ui-overlay table.w2ui-drop-menu tr.w2ui-selected td { + color: inherit; +} +.w2ui-overlay table.w2ui-drop-menu tr.w2ui-disabled { + opacity: 0.4; + background-color: white !important; +} +.w2ui-overlay table.w2ui-drop-menu .w2ui-icon { + font-size: 14px; + color: #8d99a7; + display: inline-block; + padding-top: 4px; +} +/************************************************* +* ---- Common Classes ---- +*/ +.w2ui-marker { + color: #444; + background-color: rgba(252, 244, 161, 0.48); +} +.w2ui-spinner { + display: inline-block; + background-size: 100%; + background-repeat: no-repeat; + background-image: url(data:image/gif;base64,R0lGODlhgACAAKIAAP///93d3bu7u5mZmQAA/wAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFBQAEACwCAAIAfAB8AAAD/0i63P4wygYqmDjrzbtflvWNZGliYXiubKuloivPLlzReD7al+7/Eh5wSFQIi8hHYBkwHUmD6CD5YTJLz49USuVYraRsZ7vtar7XnQ1Kjpoz6LRHvGlz35O4nEPP2O94EnpNc2sef1OBGIOFMId/inB6jSmPdpGScR19EoiYmZobnBCIiZ95k6KGGp6ni4wvqxilrqBfqo6skLW2YBmjDa28r6Eosp27w8Rov8ekycqoqUHODrTRvXsQwArC2NLF29UM19/LtxO5yJd4Au4CK7DUNxPebG4e7+8n8iv2WmQ66BtoYpo/dvfacBjIkITBE9DGlMvAsOIIZjIUAixliv9ixYZVtLUos5GjwI8gzc3iCGghypQqrbFsme8lwZgLZtIcYfNmTJ34WPTUZw5oRxdD9w0z6iOpO15MgTh1BTTJUKos39jE+o/KS64IFVmsFfYT0aU7capdy7at27dw48qdS7eu3bt480I02vUbX2F/JxYNDImw4GiGE/P9qbhxVpWOI/eFKtlNZbWXuzlmG1mv58+gQ4seTbq06dOoU6vGQZJy0FNlMcV+czhQ7SQmYd8eMhPs5BxVdfcGEtV3buDBXQ+fURxx8oM6MT9P+Fh6dOrH2zavc13u9JXVJb520Vp8dvC76wXMuN5Sepm/1WtkEZHDefnzR9Qvsd9+/wi8+en3X0ntYVcSdAE+UN4zs7ln24CaLagghIxBaGF8kFGoIYV+Ybghh841GIyI5ICIFoklJsigihmimJOLEbLYIYwxSgigiZ+8l2KB+Ml4oo/w8dijjcrouCORKwIpnJIjMnkkksalNeR4fuBIm5UEYImhIlsGCeWNNJphpJdSTlkml1jWeOY6TnaRpppUctcmFW9mGSaZceYopH9zkjnjUe59iR5pdapWaGqHopboaYua1qije67GJ6CuJAAAIfkEBQUABAAsCgACAFcAMAAAA/9Iutz+ML5Ag7w46z0r5WAoSp43nihXVmnrdusrv+s332dt4Tyo9yOBUJD6oQBIQGs4RBlHySSKyczVTtHoidocPUNZaZAr9F5FYbGI3PWdQWn1mi36buLKFJvojsHjLnshdhl4L4IqbxqGh4gahBJ4eY1kiX6LgDN7fBmQEJI4jhieD4yhdJ2KkZk8oiSqEaatqBekDLKztBG2CqBACq4wJRi4PZu1sA2+v8C6EJexrBAD1AOBzsLE0g/V1UvYR9sN3eR6lTLi4+TlY1wz6Qzr8u1t6FkY8vNzZTxaGfn6mAkEGFDgL4LrDDJDyE4hEIbdHB6ESE1iD4oVLfLAqPETIsOODwmCDJlv5MSGJklaS6khAQAh+QQFBQAEACwfAAIAVwAwAAAD/0i63P5LSAGrvTjrNuf+YKh1nWieIumhbFupkivPBEzR+GnnfLj3ooFwwPqdAshAazhEGUXJJIrJ1MGOUamJ2jQ9QVltkCv0XqFh5IncBX01afGYnDqD40u2z76JK/N0bnxweC5sRB9vF34zh4gjg4uMjXobihWTlJUZlw9+fzSHlpGYhTminKSepqebF50NmTyor6qxrLO0L7YLn0ALuhCwCrJAjrUqkrjGrsIkGMW/BMEPJcphLgDaABjUKNEh29vdgTLLIOLpF80s5xrp8ORVONgi8PcZ8zlRJvf40tL8/QPYQ+BAgjgMxkPIQ6E6hgkdjoNIQ+JEijMsasNY0RQix4gKP+YIKXKkwJIFF6JMudFEAgAh+QQFBQAEACw8AAIAQgBCAAAD/kg0PPowykmrna3dzXvNmSeOFqiRaGoyaTuujitv8Gx/661HtSv8gt2jlwIChYtc0XjcEUnMpu4pikpv1I71astytkGh9wJGJk3QrXlcKa+VWjeSPZHP4Rtw+I2OW81DeBZ2fCB+UYCBfWRqiQp0CnqOj4J1jZOQkpOUIYx/m4oxg5cuAaYBO4Qop6c6pKusrDevIrG2rkwptrupXB67vKAbwMHCFcTFxhLIt8oUzLHOE9Cy0hHUrdbX2KjaENzey9Dh08jkz8Tnx83q66bt8PHy8/T19vf4+fr6AP3+/wADAjQmsKDBf6AOKjS4aaHDgZMeSgTQcKLDhBYPEswoA1BBAgAh+QQFBQAEACxOAAoAMABXAAAD7Ei6vPOjyUkrhdDqfXHm4OZ9YSmNpKmiqVqykbuysgvX5o2HcLxzup8oKLQQix0UcqhcVo5ORi+aHFEn02sDeuWqBGCBkbYLh5/NmnldxajX7LbPBK+PH7K6narfO/t+SIBwfINmUYaHf4lghYyOhlqJWgqDlAuAlwyBmpVnnaChoqOkpaanqKmqKgGtrq+wsbA1srW2ry63urasu764Jr/CAb3Du7nGt7TJsqvOz9DR0tPU1TIA2ACl2dyi3N/aneDf4uPklObj6OngWuzt7u/d8fLY9PXr9eFX+vv8+PnYlUsXiqC3c6PmUUgAACH5BAUFAAQALE4AHwAwAFcAAAPpSLrc/m7IAau9bU7MO9GgJ0ZgOI5leoqpumKt+1axPJO1dtO5vuM9yi8TlAyBvSMxqES2mo8cFFKb8kzWqzDL7Xq/4LB4TC6bz1yBes1uu9uzt3zOXtHv8xN+Dx/x/wJ6gHt2g3Rxhm9oi4yNjo+QkZKTCgGWAWaXmmOanZhgnp2goaJdpKGmp55cqqusrZuvsJays6mzn1m4uRAAvgAvuBW/v8GwvcTFxqfIycA3zA/OytCl0tPPO7HD2GLYvt7dYd/ZX99j5+Pi6tPh6+bvXuTuzujxXens9fr7YPn+7egRI9PPHrgpCQAAIfkEBQUABAAsPAA8AEIAQgAAA/lIutz+UI1Jq7026h2x/xUncmD5jehjrlnqSmz8vrE8u7V5z/m5/8CgcEgsGo/IpHLJbDqf0Kh0ShBYBdTXdZsdbb/Yrgb8FUfIYLMDTVYz2G13FV6Wz+lX+x0fdvPzdn9WeoJGAYcBN39EiIiKeEONjTt0kZKHQGyWl4mZdREAoQAcnJhBXBqioqSlT6qqG6WmTK+rsa1NtaGsuEu6o7yXubojsrTEIsa+yMm9SL8osp3PzM2cStDRykfZ2tfUtS/bRd3ewtzV5pLo4eLjQuUp70Hx8t9E9eqO5Oku5/ztdkxi90qPg3x2EMpR6IahGocPCxp8AGtigwQAIfkEBQUABAAsHwBOAFcAMAAAA/9Iutz+MMo36pg4682J/V0ojs1nXmSqSqe5vrDXunEdzq2ta3i+/5DeCUh0CGnF5BGULC4tTeUTFQVONYAs4CfoCkZPjFar83rBx8l4XDObSUL1Ott2d1U4yZwcs5/xSBB7dBMBhgEYfncrTBGDW4WHhomKUY+QEZKSE4qLRY8YmoeUfkmXoaKInJ2fgxmpqqulQKCvqRqsP7WooriVO7u8mhu5NacasMTFMMHCm8qzzM2RvdDRK9PUwxzLKdnaz9y/Kt8SyR3dIuXmtyHpHMcd5+jvWK4i8/TXHff47SLjQvQLkU+fG29rUhQ06IkEG4X/Rryp4mwUxSgLL/7IqFETB8eONT6ChCFy5ItqJomES6kgAQAh+QQFBQAEACwKAE4AVwAwAAAD/0i63A4QuEmrvTi3yLX/4MeNUmieITmibEuppCu3sDrfYG3jPKbHveDktxIaF8TOcZmMLI9NyBPanFKJp4A2IBx4B5lkdqvtfb8+HYpMxp3Pl1qLvXW/vWkli16/3dFxTi58ZRcChwIYf3hWBIRchoiHiotWj5AVkpIXi4xLjxiaiJR/T5ehoomcnZ+EGamqq6VGoK+pGqxCtaiiuJVBu7yaHrk4pxqwxMUzwcKbyrPMzZG90NGDrh/JH8t72dq3IN1jfCHb3L/e5ebh4ukmxyDn6O8g08jt7tf26ybz+m/W9GNXzUQ9fm1Q/APoSWAhhfkMAmpEbRhFKwsvCsmosRIHx444PoKcIXKkjIImjTzjkQAAIfkEBQUABAAsAgA8AEIAQgAAA/VIBNz+8KlJq72Yxs1d/uDVjVxogmQqnaylvkArT7A63/V47/m2/8CgcEgsGo/IpHLJbDqf0Kh0Sj0FroGqDMvVmrjgrDcTBo8v5fCZki6vCW33Oq4+0832O/at3+f7fICBdzsChgJGeoWHhkV0P4yMRG1BkYeOeECWl5hXQ5uNIAOjA1KgiKKko1CnqBmqqk+nIbCkTq20taVNs7m1vKAnurtLvb6wTMbHsUq4wrrFwSzDzcrLtknW16tI2tvERt6pv0fi48jh5h/U6Zs77EXSN/BE8jP09ZFA+PmhP/xvJgAMSGBgQINvEK5ReIZhQ3QEMTBLAAAh+QQFBQAEACwCAB8AMABXAAAD50i6DA4syklre87qTbHn4OaNYSmNqKmiqVqyrcvBsazRpH3jmC7yD98OCBF2iEXjBKmsAJsWHDQKmw571l8my+16v+CweEwum8+hgHrNbrvbtrd8znbR73MVfg838f8BeoB7doN0cYZvaIuMjY6PkJGSk2gClgJml5pjmp2YYJ6dX6GeXaShWaeoVqqlU62ir7CXqbOWrLafsrNctjIDwAMWvC7BwRWtNsbGFKc+y8fNsTrQ0dK3QtXAYtrCYd3eYN3c49/a5NVj5eLn5u3s6e7x8NDo9fbL+Mzy9/T5+tvUzdN3Zp+GBAAh+QQJBQAEACwCAAIAfAB8AAAD/0i63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+cCzPdArcQK2TOL7/nl4PSMwIfcUk5YhUOh3M5nNKiOaoWCuWqt1Ou16l9RpOgsvEMdocXbOZ7nQ7DjzTaeq7zq6P5fszfIASAYUBIYKDDoaGIImKC4ySH3OQEJKYHZWWi5iZG0ecEZ6eHEOio6SfqCaqpaytrpOwJLKztCO2jLi1uoW8Ir6/wCHCxMG2x7muysukzb230M6H09bX2Nna29zd3t/g4cAC5OXm5+jn3Ons7eba7vHt2fL16tj2+QL0+vXw/e7WAUwnrqDBgwgTKlzIsKHDh2gGSBwAccHEixAvaqTYcFCjRoYeNyoM6REhyZIHT4o0qPIjy5YTTcKUmHImx5cwE85cmJPnSYckK66sSAAj0aNIkypdyrSp06dQo0qdSrWq1atYs2rdyrWr169gwxZJAAA7); +} +/* common icons */ +.w2ui-icon { + background-repeat: no-repeat; + height: 16px; + width: 16px; + overflow: hidden; + margin: 2px 2px; + display: inline-block; +} +.w2ui-icon.icon-search, +.w2ui-icon.icon-search-down { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAgCAYAAAB+ZAqzAAACuElEQVRYw9WXSWhTQRjHR0UKLqhFaV0OUih68GAOWjyJKypCpAoV8aIiioIICiKiB1GMtE3MYmry2moXDz1UDx7sUXHBhQpSaRVxrYpWcMO9avx/8AJh/CbznHkxdeB3Cd/8589kvuUJkWcdjCTHghUgAi6DJ+AVeAqugSQIggniXywcNBJsB70g44EHYBcYXUhTM8EFj4ZkboKqQpiqAv2GprK8o7/f75t6pjn0M3gNPmri3vtycxAZA64qDvkJ2kENqAQTQQWoBg74qth3B4y3NbZDIX4fzNfsnQtuK/YfsjFVCh4pMq3Co0Y5uMVoUGkpy8aFT5xaeSzVEo45bXdBt4LeaLq1k0RXMYJfdDfFmAuAD4zWlty4UNyZEkm19MUb2zMw8Sfp1u+IWSrcIimLnTG8/SijdU6OO5poDESdtgHZVBzUHm/amhW7zoitMTS2mNHqASPk2FDCCcLMYK6p+obmulyxfiYLA4bGKFvfSnrUvkq5+Lpk8z4yRH8r3l/X4WiqJFfspSQ0CGYZGpsMnkt6L+h31Z76hpMdeOwPQ7H0NFnssST0C8wxNDaDKb6kP06150gsHahNNlVzYheZd7HJ0BiX4VRGhpmIhRixKyZilM2M1mnTArtIUbU3/qVO0H0GvmQ4CY4C3YopYYlHjXlggNG4R33Ypi2tVtwaPeTdNMkq9pVQZQdvFPs32zbx4aAjzxhDRfIAWAeWg7VgrzsY5ht/zoNJtubKwA3LITGjSKRyW3NTwaUCmKOSMd3WHH0ZJRQZZkOP1zFKZ3CB++4+aQ6kEeksWAb2a2L7qDv49S1Q6T72MOgEXa6RGFhP3wpS/B6NOWpRs0UxFg7eqTFHjX1hscxtAz/ymEuIYi0cvgF8Y0w5Ro3dZ3M1boJkTaXEUFlug6fsdsRQWzTj0cey+N/Xb2sj5lTh2M6OAAAAAElFTkSuQmCC) no-repeat center !important; + background-size: 14px 12px !important; + opacity: 0.9; +} +.w2ui-icon.icon-folder { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLxZO7ihRBFIa/6u0ZW7GHBUV0UQQTZzd3QdhMQxOfwMRXEANBMNQX0MzAzFAwEzHwARbNFDdwEd31Mj3X7a6uOr9BtzNjYjKBJ6nicP7v3KqcJFaxhBVtZUAK8OHlld2st7Xl3DJPVONP+zEUV4HqL5UDYHr5xvuQAjgl/Qs7TzvOOVAjxjlC+ePSwe6DfbVegLVuT4r14eTr6zvA8xSAoBLzx6pvj4l+DZIezuVkG9fY2H7YRQIMZIBwycmzH1/s3F8AapfIPNF3kQk7+kw9PWBy+IZOdg5Ug3mkAATy/t0usovzGeCUWTjCz0B+Sj0ekfdvkZ3abBv+U4GaCtJ1iEm6ANQJ6fEzrG/engcKw/wXQvEKxSEKQxRGKE7Izt+DSiwBJMUSm71rguMYhQKrBygOIRStf4TiFFRBvbRGKiQLWP29yRSHKBTtfdBmHs0BUpgvtgF4yRFR+NUKi0XZcYjCeCG2smkzLAHkbRBmP0/Uk26O5YnUActBp1GsAI+S5nRJJJal5K1aAMrq0d6Tm9uI6zjyf75dAe6tx/SsWeD//o2/Ab6IH3/h25pOAAAAAElFTkSuQmCC) no-repeat center !important; +} +.w2ui-icon.icon-page { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAINSURBVBgZBcG/r55zGAfg6/4+z3va01NHlYgzEfE7MdCIGISFgS4Gk8ViYyM2Mdlsko4GSf8Do0FLRCIkghhYJA3aVBtEz3nP89wf11VJvPDepdd390+8Nso5nESBQoq0pfvXm9fzWf19453LF85vASqJlz748vInb517dIw6EyYBIIG49u+xi9/c9MdvR//99MPPZ7+4cP4IZhhTPbwzT2d+vGoaVRRp1rRliVvHq+cfvM3TD82+7mun0o/ceO7NT+/4/KOXjwZU1ekk0840bAZzMQ2mooqh0A72d5x/6sB9D5zYnff3PoYBoWBgFKPKqDKqjCpjKr//dcu9p489dra88cydps30KswACfNEKanSaxhlntjJ8Mv12Paie+vZ+0+oeSwwQ0Iw1xAR1CiFNJkGO4wu3ZMY1AAzBI0qSgmCNJsJUEOtJSMaCTBDLyQ0CknAGOgyTyFFiLI2awMzdEcSQgSAAKVUmAeNkxvWJWCGtVlDmgYQ0GFtgg4pNtOwbBcwQy/Rife/2yrRRVI0qYCEBly8Z+P4qMEMy7JaVw72N568e+iwhrXoECQkfH91kY7jwwXMsBx1L93ZruqrK6uuiAIdSnTIKKPLPFcvay8ww/Hh+ufeznTXu49v95IMoQG3784gYXdTqvRmqn/Wpa/ADFX58MW3L71SVU9ETgEIQQQIOOzub+fhIvwPRDgeVjWDahIAAAAASUVORK5CYII=) no-repeat center !important; +} +/************************************************* +* ---- Locking portion of the screen (in grid, form, layout) +*/ +.w2ui-lock { + display: none; + position: absolute; + z-index: 1400; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + opacity: 0.15; + filter: alpha(opacity=15); + background-color: #333333; +} +.w2ui-lock-msg { + display: none; + position: absolute; + z-index: 1400; + top: 45%; + left: 50%; + -webkit-transform: translateX(-50%) translateY(-50%); + -moz-transform: translateX(-50%) translateY(-50%); + -ms-transform: translateX(-50%) translateY(-50%); + -o-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); + width: 200px; + height: 80px; + padding: 30px 8px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + font-size: 13px; + font-family: Verdana, Arial, sans-serif; + opacity: 0.8; + filter: alpha(opacity=80); + background-color: #555555; + color: #ffffff; + text-align: center; + border-radius: 5px; + border: 2px solid #444444; +} +.w2ui-lock-msg .w2ui-spinner { + display: inline-block; + width: 24px; + height: 24px; + margin: -3px 8px -7px -10px; +} +/************************************************* +* ---- Scroll contet, used in toolbar and tabs ---- +*/ +.w2ui-scroll-wrapper { + overflow: hidden; +} +.w2ui-scroll-left, +.w2ui-scroll-right { + top: 0; + width: 18px; + height: 100%; + cursor: default !important; + z-index: 10; + display: none; + position: absolute; +} +.w2ui-scroll-left:hover, +.w2ui-scroll-right:hover { + background-color: #dddddd; +} +.w2ui-scroll-left { + left: 0; + box-shadow: 0px 0px 7px #5F5F5F; + background: #f7f7f7 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAzklEQVR4Ae2THRDEMBCFzy1ucatb3eJ2uhi3uNUtbnGrW9zi1rOdNzdvdl7nDpvYt/9/r7+/51myZZf/zXkD2iMHHRSb0x3oskwMieK05PwEXqP4ExSL0wp0ROao2OOuMPOMdUL6XU1/oGLcFWb+NqyTd2W/P/2qTr9h+nFXhOkHXRHiNyjrgp/U/V+WaQcaNY13zZI0A1JvcVqAnrGDTdtDtZUHjHIJhxxVLN0iqXgCP1l/7h8U9kc6abyJ4/eNWPpGdBv+XdUK0K8cnvcBly2rDr7C1HQAAAAASUVORK5CYII=') center center no-repeat; + background-size: 15px 12px; +} +.w2ui-scroll-right { + right: 0; + box-shadow: 0px 0px 7px #5F5F5F; + background: #f7f7f7 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAz0lEQVR4Ae2UG7TGMBCEr1vd4la3uMUtuli3utWtbnGLW9zi9l/bDMzJG7u12cfJfLunf1+UEC9Bv0vVQwJ8hjRCaZafflb1C9RQf4OD0gSDE+i+PiJAabFhQc1y1AYYsJGLY3lgxM17uWPO56yPiFDqVPWgRtpIHSd1zPnwkBsdI58OlNwx4fP2X0TgfMTOoHSdKOXkpyNvEyQh7ul+4swxJSTQuwNDxz68l/ukVNbu0Neen5Z+KvzWxBAqHds349uPFJ/jVOrPjxUq++OLf+20q5+noXo0AAAAAElFTkSuQmCC') center center no-repeat; + background-size: 15px 13px; +} +button.w2ui-btn { + position: relative; + display: inline-block; + border-radius: 4px; + margin: 0px 5px; + padding: 6px 12px; + color: #666; + font-size: 12px; + border: 1px solid #B6B6B6; + background-image: -webkit-linear-gradient(#ffffff 0%, #e7e7e7 100%); + background-image: -moz-linear-gradient(#ffffff 0%, #e7e7e7 100%); + background-image: -ms-linear-gradient(#ffffff 0%, #e7e7e7 100%); + background-image: -o-linear-gradient(#ffffff 0%, #e7e7e7 100%); + background-image: linear-gradient(#ffffff 0%, #e7e7e7 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffe7e7e7', endColorstr='#ffffffff', GradientType=0); + outline: none; + box-shadow: 0px 1px 0px white; + cursor: default; + min-width: 75px; + line-height: 110%; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +button.w2ui-btn:hover { + text-decoration: none; + border: 1px solid #bbb; + background-image: -webkit-linear-gradient(#f7f7f7 0%, #dddddd 100%); + background-image: -moz-linear-gradient(#f7f7f7 0%, #dddddd 100%); + background-image: -ms-linear-gradient(#f7f7f7 0%, #dddddd 100%); + background-image: -o-linear-gradient(#f7f7f7 0%, #dddddd 100%); + background-image: linear-gradient(#f7f7f7 0%, #dddddd 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffdddddd', endColorstr='#fff7f7f7', GradientType=0); + color: #333; +} +button.w2ui-btn:active, +button.w2ui-btn.clicked { + border: 1px solid #999; + background-image: -webkit-linear-gradient(#cccccc 0%, #cccccc 100%); + background-image: -moz-linear-gradient(#cccccc 0%, #cccccc 100%); + background-image: -ms-linear-gradient(#cccccc 0%, #cccccc 100%); + background-image: -o-linear-gradient(#cccccc 0%, #cccccc 100%); + background-image: linear-gradient(#cccccc 0%, #cccccc 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffcccccc', endColorstr='#ffcccccc', GradientType=0); + text-shadow: 1px 1px 1px #eee; +} +button.w2ui-btn:disabled { + border: 1px solid #bbb !important; + background: #f7f7f7 !important; + color: #bdbcbc !important; + text-shadow: none !important; +} +button.w2ui-btn:focus:before { + content: ""; + border: 1px dashed #aaa; + border-radius: 3px; + position: absolute; + top: 2px; + bottom: 2px; + left: 2px; + right: 2px; + pointer-events: none; +} +button.w2ui-btn::-moz-focus-inner { + border: 0; +} +button.w2ui-btn-blue { + color: white; + background-image: -webkit-linear-gradient(#80c0f7 0%, #269df0 100%); + background-image: -moz-linear-gradient(#80c0f7 0%, #269df0 100%); + background-image: -ms-linear-gradient(#80c0f7 0%, #269df0 100%); + background-image: -o-linear-gradient(#80c0f7 0%, #269df0 100%); + background-image: linear-gradient(#80c0f7 0%, #269df0 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff269df0', endColorstr='#ff80c0f7', GradientType=0); + border: 1px solid #538AB7; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-blue:hover { + color: white; + background-image: -webkit-linear-gradient(#73b6f0 0%, #2391dd 100%); + background-image: -moz-linear-gradient(#73b6f0 0%, #2391dd 100%); + background-image: -ms-linear-gradient(#73b6f0 0%, #2391dd 100%); + background-image: -o-linear-gradient(#73b6f0 0%, #2391dd 100%); + background-image: linear-gradient(#73b6f0 0%, #2391dd 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff2391dd', endColorstr='#ff73b6f0', GradientType=0); + border: 1px solid #497BA3; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-blue:active, +button.w2ui-btn-blue.clicked { + color: white; + background-image: -webkit-linear-gradient(#1e83c9 0%, #1e83c9 100%); + background-image: -moz-linear-gradient(#1e83c9 0%, #1e83c9 100%); + background-image: -ms-linear-gradient(#1e83c9 0%, #1e83c9 100%); + background-image: -o-linear-gradient(#1e83c9 0%, #1e83c9 100%); + background-image: linear-gradient(#1e83c9 0%, #1e83c9 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff1e83c9', endColorstr='#ff1e83c9', GradientType=0); + border: 1px solid #1268A6; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-blue:focus:before { + border: 1px dashed #e8e8e8; +} +button.w2ui-btn-green { + color: white; + background-image: -webkit-linear-gradient(#81cf81 0%, #52a452 100%); + background-image: -moz-linear-gradient(#81cf81 0%, #52a452 100%); + background-image: -ms-linear-gradient(#81cf81 0%, #52a452 100%); + background-image: -o-linear-gradient(#81cf81 0%, #52a452 100%); + background-image: linear-gradient(#81cf81 0%, #52a452 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff52a452', endColorstr='#ff81cf81', GradientType=0); + border: 1px solid #479247; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-green:hover { + color: white; + background-image: -webkit-linear-gradient(#6abe68 0%, #3f8f3d 100%); + background-image: -moz-linear-gradient(#6abe68 0%, #3f8f3d 100%); + background-image: -ms-linear-gradient(#6abe68 0%, #3f8f3d 100%); + background-image: -o-linear-gradient(#6abe68 0%, #3f8f3d 100%); + background-image: linear-gradient(#6abe68 0%, #3f8f3d 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff3f8f3d', endColorstr='#ff6abe68', GradientType=0); + border: 1px solid #479247; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-green:active, +button.w2ui-btn-green.clicked { + color: white; + background-image: -webkit-linear-gradient(#377d36 0%, #377d36 100%); + background-image: -moz-linear-gradient(#377d36 0%, #377d36 100%); + background-image: -ms-linear-gradient(#377d36 0%, #377d36 100%); + background-image: -o-linear-gradient(#377d36 0%, #377d36 100%); + background-image: linear-gradient(#377d36 0%, #377d36 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff377d36', endColorstr='#ff377d36', GradientType=0); + border: 1px solid #555 !important; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-green:focus:before { + border: 1px dashed #e8e8e8; +} +button.w2ui-btn-orange { + color: white; + background-image: -webkit-linear-gradient(#fcc272 0%, #fb8822 100%); + background-image: -moz-linear-gradient(#fcc272 0%, #fb8822 100%); + background-image: -ms-linear-gradient(#fcc272 0%, #fb8822 100%); + background-image: -o-linear-gradient(#fcc272 0%, #fb8822 100%); + background-image: linear-gradient(#fcc272 0%, #fb8822 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fffb8822', endColorstr='#fffcc272', GradientType=0); + border: 1px solid #B68B4C; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-orange:hover { + color: white; + background-image: -webkit-linear-gradient(#f4ad59 0%, #f1731f 100%); + background-image: -moz-linear-gradient(#f4ad59 0%, #f1731f 100%); + background-image: -ms-linear-gradient(#f4ad59 0%, #f1731f 100%); + background-image: -o-linear-gradient(#f4ad59 0%, #f1731f 100%); + background-image: linear-gradient(#f4ad59 0%, #f1731f 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fff1731f', endColorstr='#fff4ad59', GradientType=0); + border: 1px solid #B68B4C; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-orange:active, +button.w2ui-btn-orange.clicked { + color: white; + border: 1px solid #666; + background-image: -webkit-linear-gradient(#b98747 0%, #b98747 100%); + background-image: -moz-linear-gradient(#b98747 0%, #b98747 100%); + background-image: -ms-linear-gradient(#b98747 0%, #b98747 100%); + background-image: -o-linear-gradient(#b98747 0%, #b98747 100%); + background-image: linear-gradient(#b98747 0%, #b98747 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffb98747', endColorstr='#ffb98747', GradientType=0); + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-orange:focus:before { + border: 1px dashed #f9f9f9; +} +button.w2ui-btn-red { + color: white; + background-image: -webkit-linear-gradient(#ff6e70 0%, #c72d2d 100%); + background-image: -moz-linear-gradient(#ff6e70 0%, #c72d2d 100%); + background-image: -ms-linear-gradient(#ff6e70 0%, #c72d2d 100%); + background-image: -o-linear-gradient(#ff6e70 0%, #c72d2d 100%); + background-image: linear-gradient(#ff6e70 0%, #c72d2d 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffc72d2d', endColorstr='#ffff6e70', GradientType=0); + border: 1px solid #BB3C3E; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-red:hover { + color: white; + background-image: -webkit-linear-gradient(#ee696c 0%, #ae2527 100%); + background-image: -moz-linear-gradient(#ee696c 0%, #ae2527 100%); + background-image: -ms-linear-gradient(#ee696c 0%, #ae2527 100%); + background-image: -o-linear-gradient(#ee696c 0%, #ae2527 100%); + background-image: linear-gradient(#ee696c 0%, #ae2527 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffae2527', endColorstr='#ffee696c', GradientType=0); + border: 1px solid #BB3C3E; + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-red:active, +button.w2ui-btn-red.clicked { + color: white; + border: 1px solid #861C1E; + background-image: -webkit-linear-gradient(#9c2123 0%, #9c2123 100%); + background-image: -moz-linear-gradient(#9c2123 0%, #9c2123 100%); + background-image: -ms-linear-gradient(#9c2123 0%, #9c2123 100%); + background-image: -o-linear-gradient(#9c2123 0%, #9c2123 100%); + background-image: linear-gradient(#9c2123 0%, #9c2123 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff9c2123', endColorstr='#ff9c2123', GradientType=0); + text-shadow: 0px 0px 1px #111111; +} +button.w2ui-btn-red:focus:before { + border: 1px dashed #ddd; +} +button.w2ui-btn-small { + padding: 5px !important; + margin: 0px; + min-width: 0px; +} +button.w2ui-btn-small:focus:before { + border-radius: 2px; + top: 2px; + bottom: 2px; + left: 2px; + right: 2px; +} +/************************************************* +* ---- Forms ---- +*/ +.w2ui-form { + position: relative; + color: #000000; + background-color: #f2f2f2; + border: 1px solid #c0c0c0; + border-radius: 3px; + padding: 0px; + overflow: hidden !important; +} +.w2ui-form > div { + position: absolute; + overflow: hidden; +} +.w2ui-form .w2ui-form-header { + position: absolute; + left: 0; + right: 0; + border-bottom: 1px solid #99bbe8 !important; + overflow: hidden; + color: #444444; + font-size: 13px; + text-align: center; + padding: 8px; + background-image: -webkit-linear-gradient(#dae6f3, #c2d5ed); + background-image: -moz-linear-gradient(#dae6f3, #c2d5ed); + background-image: -ms-linear-gradient(#dae6f3, #c2d5ed); + background-image: -o-linear-gradient(#dae6f3, #c2d5ed); + background-image: linear-gradient(#dae6f3, #c2d5ed); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffdae6f3', endColorstr='#ffc2d5ed', GradientType=0); + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.w2ui-form .w2ui-form-toolbar { + position: absolute; + left: 0px; + right: 0px; + margin: 0px; + padding: 6px 3px; + border-bottom: 1px solid #d5d8d8; +} +.w2ui-form .w2ui-form-tabs { + margin: 0px; + padding: 0px; +} +.w2ui-form .w2ui-tabs { + position: absolute; + left: 0; + right: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + padding-top: 5px !important; + background-color: #fafafa; +} +.w2ui-form .w2ui-tabs .w2ui-tab.active { + background-color: #f2f2f2; +} +.w2ui-form .w2ui-page { + position: absolute; + left: 0; + right: 0; + overflow: auto; + padding: 10px; + border-left: 1px solid inherit; + border-right: 1px solid inherit; + background-color: inherit; + border-radius: 3px; +} +.w2ui-form .w2ui-buttons { + position: absolute; + left: 0; + right: 0; + bottom: 0; + text-align: center; + border-top: 1px solid #d5d8d8; + border-bottom: 0px solid #d5d8d8; + background-color: #fafafa; + padding: 15px 0px !important; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +} +.w2ui-form .w2ui-buttons input[type="button"], +.w2ui-form .w2ui-buttons button { + min-width: 80px; + margin-right: 5px; +} +.w2ui-form input[type=checkbox], +.w2ui-form input[type=radio] { + margin-top: 4px; + margin-bottom: 4px; +} +.w2ui-form input[type=checkbox].w2ui-toggle { + margin: 0px; +} +.w2ui-group-title { + padding: 5px 2px; + color: #8D96A2; + text-shadow: 1px 1px 2px #fdfdfd; + font-size: 120%; +} +.w2ui-group { + background-color: #f9f9f9; + margin: 5px 0px 10px 0px; + padding: 10px 5px; + border-top: 1px solid #dcdcdc; + border-bottom: 1px solid #dcdcdc; +} +.w2ui-field > label { + display: block; + float: left; + margin-top: 7px; + margin-bottom: 3px; + width: 120px; + padding: 0px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-align: right; + min-height: 20px; + color: #666; +} +.w2ui-field > div { + /* do not include width */ + margin-bottom: 3px; + margin-left: 128px; + padding: 3px; + min-height: 28px; + float: none; +} +.w2ui-field.w2ui-required > div { + position: relative; +} +.w2ui-field.w2ui-required > div::before { + content: '*'; + position: absolute; + margin-top: 5px; + margin-left: -9px; + color: #ff0000; +} +.w2ui-field.w2ui-span1 > label { + width: 20px; +} +.w2ui-field.w2ui-span1 > div { + margin-left: 28px; +} +.w2ui-field.w2ui-span2 > label { + width: 40px; +} +.w2ui-field.w2ui-span2 > div { + margin-left: 48px; +} +.w2ui-field.w2ui-span3 > label { + width: 60px; +} +.w2ui-field.w2ui-span3 > div { + margin-left: 68px; +} +.w2ui-field.w2ui-span4 > label { + width: 80px; +} +.w2ui-field.w2ui-span4 > div { + margin-left: 88px; +} +.w2ui-field.w2ui-span5 > label { + width: 100px; +} +.w2ui-field.w2ui-span5 > div { + margin-left: 108px; +} +.w2ui-field.w2ui-span6 > label { + width: 120px; +} +.w2ui-field.w2ui-span6 > div { + margin-left: 128px; +} +.w2ui-field.w2ui-span7 > label { + width: 140px; +} +.w2ui-field.w2ui-span7 > div { + margin-left: 148px; +} +.w2ui-field.w2ui-span8 > label { + width: 160px; +} +.w2ui-field.w2ui-span8 > div { + margin-left: 168px; +} +.w2ui-field.w2ui-span9 > label { + width: 180px; +} +.w2ui-field.w2ui-span9 > div { + margin-left: 188px; +} +.w2ui-field.w2ui-span10 > label { + width: 200px; +} +.w2ui-field.w2ui-span10 > div { + margin-left: 208px; +} +.w2ui-error { + border: 1px solid #ffa8a8 !important; + background-color: #fff4eb !important; +} +.w2field { + padding: 3px; + border-radius: 3px; + border: 1px solid silver; +} +.w2ui-field-helper { + position: absolute; + display: inline-block; + line-height: 100%; + /* pointer-events: none; - do not use as IE does not support it */ + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; +} +.w2ui-field-helper .w2ui-field-up { + position: absolute; + top: 0px; + padding: 2px 3px; +} +.w2ui-field-helper .w2ui-field-down { + position: absolute; + bottom: 0px; + padding: 2px 3px; +} +.w2ui-field-helper .arrow-up:hover { + border-bottom-color: #81C6FF; +} +.w2ui-field-helper .arrow-down:hover { + border-top-color: #81C6FF; +} +/* +* ARROWS +*/ +.arrow-up { + background: none; + width: 0; + height: 0; + border-left: 4px solid transparent; + /* left arrow slant */ + border-right: 4px solid transparent; + /* right arrow slant */ + border-bottom: 5px solid #777; + /* bottom, add background color here */ + font-size: 0; + line-height: 0; +} +.arrow-down { + background: none; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 5px solid #777; + font-size: 0; + line-height: 0; +} +.arrow-left { + background: none; + width: 0; + height: 0; + border-bottom: 4px solid transparent; + /* left arrow slant */ + border-top: 4px solid transparent; + /* right arrow slant */ + border-right: 5px solid #777; + /* bottom, add background color here */ + font-size: 0; + line-height: 0; +} +.arrow-right { + background: none; + width: 0; + height: 0; + border-bottom: 4px solid transparent; + /* left arrow slant */ + border-top: 4px solid transparent; + /* right arrow slant */ + border-left: 5px solid #777; + /* bottom, add background color here */ + font-size: 0; + line-height: 0; +} +/* +* COLOR overlay +*/ +.w2ui-color { + padding: 5px; + padding-top: 8px; + background-color: white; + border-radius: 3px; +} +.w2ui-color > table { + table-layout: fixed; + width: 160px; +} +.w2ui-color > table td { + width: 20px; + height: 20px; + text-align: center; +} +.w2ui-color > table td div { + cursor: pointer; + display: inline-block; + width: 16px; + height: 17px; + padding: 1px 4px; + border: 1px solid transparent; + color: white; + text-shadow: 0px 0px 2px #000; +} +.w2ui-color > table td div:hover { + outline: 1px solid #666; + border: 1px solid #fff; +} +/* +* DATE overlay +*/ +.w2ui-calendar { + margin: 0px; + padding: 1px; + line-height: 108%; +} +.w2ui-calendar .w2ui-calendar-title { + margin: 0px -1px; + padding: 7px 2px; + background-image: -webkit-linear-gradient(#f6f6f6, #d9d9d9); + background-image: -moz-linear-gradient(#f6f6f6, #d9d9d9); + background-image: -ms-linear-gradient(#f6f6f6, #d9d9d9); + background-image: -o-linear-gradient(#f6f6f6, #d9d9d9); + background-image: linear-gradient(#f6f6f6, #d9d9d9); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fff6f6f6', endColorstr='#ffd9d9d9', GradientType=0); + border-bottom: 1px solid #bbbbbb; + color: #555555; + text-align: center; + text-shadow: 1px 1px 1px #eeeeee; + cursor: pointer; +} +.w2ui-calendar .w2ui-calendar-jump { + position: absolute; + top: 27px; + left: 0px; + right: 0px; + bottom: 0px; + background-color: #FaFaFa; +} +.w2ui-calendar .w2ui-calendar-jump > :first-child { + position: absolute; + top: 0px; + left: 0px; + bottom: 0px; + width: 110px; + overflow: hidden; + padding-top: 5px; + border-right: 1px solid #c0c0c0; +} +.w2ui-calendar .w2ui-calendar-jump > :last-child { + position: absolute; + top: 0px; + right: 0px; + bottom: 0px; + width: 88px; + overflow-x: hidden; + overflow-y: auto; + padding-top: 5px; + text-align: center; +} +.w2ui-calendar .w2ui-calendar-jump .w2ui-jump-month, +.w2ui-calendar .w2ui-calendar-jump .w2ui-jump-year { + display: inline-block; + padding: 5px 0px; + text-align: center; + float: left; + margin: 2px; + width: 50px; + cursor: default; + border: 1px solid transparent; + border-radius: 2px; +} +.w2ui-calendar .w2ui-calendar-jump .w2ui-jump-year { + float: none; + width: 95%; +} +.w2ui-calendar .w2ui-calendar-jump .w2ui-jump-month:hover, +.w2ui-calendar .w2ui-calendar-jump .w2ui-jump-year:hover { + border: 1px solid #cccccc; + color: #000000; + background-color: #efefef; +} +.w2ui-calendar .w2ui-calendar-jump .w2ui-jump-month.selected, +.w2ui-calendar .w2ui-calendar-jump .w2ui-jump-year.selected { + border: 1px solid #cccccc; + color: #000000; + background-color: #dadada; +} +.w2ui-calendar .w2ui-calendar-previous, +.w2ui-calendar .w2ui-calendar-next { + width: 24px; + height: 20px; + color: #666666; + border: 1px solid transparent; + border-radius: 3px; + padding: 2px 3px 1px 2px; + margin: -4px 0px 0px 0px; + cursor: default; +} +.w2ui-calendar .w2ui-calendar-previous:hover, +.w2ui-calendar .w2ui-calendar-next:hover { + border: 1px solid #c0c0c0; + background-color: #efefef; +} +.w2ui-calendar .w2ui-calendar-previous > div, +.w2ui-calendar .w2ui-calendar-next > div { + position: absolute; + border-left: 4px solid #888; + border-top: 4px solid #888; + border-right: 4px solid transparent; + border-bottom: 4px solid transparent; + width: 0px; + height: 0px; + padding: 0px; + margin: 3px 0px 0px 0px; +} +.w2ui-calendar .w2ui-calendar-previous { + float: left; +} +.w2ui-calendar .w2ui-calendar-previous > div { + -webkit-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -ms-transform: rotate(-45deg); + -o-transform: rotate(-45deg); + transform: rotate(-45deg); + margin-left: 6px; +} +.w2ui-calendar .w2ui-calendar-next { + float: right; +} +.w2ui-calendar .w2ui-calendar-next > div { + -webkit-transform: rotate(135deg); + -moz-transform: rotate(135deg); + -ms-transform: rotate(135deg); + -o-transform: rotate(135deg); + transform: rotate(135deg); + margin-left: 2px; + margin-right: 2px; +} +.w2ui-calendar .w2ui-calendar-now { + cursor: pointer; + margin-bottom: 10px; + text-align: center; +} +.w2ui-calendar .w2ui-calendar-now:hover { + color: #0A96DE; +} +.w2ui-calendar table.w2ui-calendar-days { + padding: 0px; +} +.w2ui-calendar table.w2ui-calendar-days td { + border: 1px solid #ffffff; + color: #000000; + background-color: #f9f9f9; + padding: 6px; + cursor: default; + text-align: right; +} +.w2ui-calendar table.w2ui-calendar-days td.w2ui-saturday, +.w2ui-calendar table.w2ui-calendar-days td.w2ui-sunday { + border: 1px solid #ffffff; + color: #c8493b; + background-color: #f9f9f9; +} +.w2ui-calendar table.w2ui-calendar-days td.w2ui-saturday:hover, +.w2ui-calendar table.w2ui-calendar-days td.w2ui-sunday:hover { + border: 1px solid #cccccc; + color: #000000; + background-color: #e9e9e9; +} +.w2ui-calendar table.w2ui-calendar-days td.w2ui-saturday.w2ui-blocked, +.w2ui-calendar table.w2ui-calendar-days td.w2ui-sunday.w2ui-blocked { + text-decoration: line-through; + border: 1px solid #ffffff; + color: #cccccc; + background-color: #ffffff; +} +.w2ui-calendar table.w2ui-calendar-days td.w2ui-today { + color: #000000; + background-color: #e2f7cd; +} +.w2ui-calendar table.w2ui-calendar-days td:hover { + border: 1px solid #cccccc; + color: #000000; + background-color: #e9e9e9; +} +.w2ui-calendar table.w2ui-calendar-days td.w2ui-date-selected { + border: 1px solid #8cb067; +} +.w2ui-calendar table.w2ui-calendar-days td.w2ui-blocked { + text-decoration: line-through; + border: 1px solid #ffffff; + color: #cccccc; + background-color: #ffffff; +} +.w2ui-calendar table.w2ui-calendar-days td.w2ui-day-empty { + border: 1px solid #ffffff; + background-color: #fdfdfd; +} +.w2ui-calendar table.w2ui-calendar-days tr.w2ui-day-title td { + border: 1px solid #ffffff; + color: #808080; + background-color: #ffffff; + text-align: center; + padding: 6px; +} +/* +* Time +*/ +.w2ui-calendar-time { + padding: 5px; + cursor: default; +} +.w2ui-calendar-time td div { + padding: 7px 10px; + text-align: center; + border: 1px solid transparent; + white-space: nowrap; +} +.w2ui-calendar-time td:nth-child(even) { + background-color: #f6f6f6; +} +.w2ui-calendar-time td div:hover { + border: 1px solid #cccccc; + color: #000000; + background-color: #e9e9e9; +} +.w2ui-calendar-time td div.w2ui-blocked { + text-decoration: line-through; + border: 1px solid #ffffff; + color: #cccccc; + background-color: #ffffff; +} +.w2ui-select { + cursor: default; + color: black !important; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAALCAQAAACnzwd+AAAAcklEQVR4AcXMsQFBQQDG4P9tAgC0gJYRQJZgKQMwCqCku6vVAAAA+NJHP4KHOk0aV2pRw61n4BBmyOxKQ8I4ehZeuhd3HTx6DQEGZ7sBfr2OOOOj3Yi43kMKs9sZknofOexqZ8npMygwWZTX51CipP+YA1OiZJbYYg9lAAAAAElFTkSuQmCC'), -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAALCAQAAACnzwd+AAAAcklEQVR4AcXMsQFBQQDG4P9tAgC0gJYRQJZgKQMwCqCku6vVAAAA+NJHP4KHOk0aV2pRw61n4BBmyOxKQ8I4ehZeuhd3HTx6DQEGZ7sBfr2OOOOj3Yi43kMKs9sZknofOexqZ8npMygwWZTX51CipP+YA1OiZJbYYg9lAAAAAElFTkSuQmCC'), -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAALCAQAAACnzwd+AAAAcklEQVR4AcXMsQFBQQDG4P9tAgC0gJYRQJZgKQMwCqCku6vVAAAA+NJHP4KHOk0aV2pRw61n4BBmyOxKQ8I4ehZeuhd3HTx6DQEGZ7sBfr2OOOOj3Yi43kMKs9sZknofOexqZ8npMygwWZTX51CipP+YA1OiZJbYYg9lAAAAAElFTkSuQmCC'), -ms-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAALCAQAAACnzwd+AAAAcklEQVR4AcXMsQFBQQDG4P9tAgC0gJYRQJZgKQMwCqCku6vVAAAA+NJHP4KHOk0aV2pRw61n4BBmyOxKQ8I4ehZeuhd3HTx6DQEGZ7sBfr2OOOOj3Yi43kMKs9sZknofOexqZ8npMygwWZTX51CipP+YA1OiZJbYYg9lAAAAAElFTkSuQmCC'), -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAALCAQAAACnzwd+AAAAcklEQVR4AcXMsQFBQQDG4P9tAgC0gJYRQJZgKQMwCqCku6vVAAAA+NJHP4KHOk0aV2pRw61n4BBmyOxKQ8I4ehZeuhd3HTx6DQEGZ7sBfr2OOOOj3Yi43kMKs9sZknofOexqZ8npMygwWZTX51CipP+YA1OiZJbYYg9lAAAAAElFTkSuQmCC'), linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-size: 17px 6px, 100% 100%; + background-position: right center, left top; + background-repeat: no-repeat, no-repeat; +} +.w2ui-select[readonly], +.w2ui-select[disabled] { + background-image: none; + background-color: #f1f1f1 !important; + color: #777 !important; +} +/* +* ENUM items +*/ +.w2ui-list { + color: inherit; + position: absolute; + padding: 0px; + margin: 0px; + min-height: 25px; + overflow: auto; + border: 1px solid #c0c0c0; + border-radius: 3px; + font-size: 6px; + line-height: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; + background-color: #ffffff; +} +.w2ui-list input[type=text] { + -webkit-box-shadow: none; + -moz-box-shadow: none; + -ms-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; +} +.w2ui-list ul { + list-style-type: none; + background-color: black; + margin: 0px; + padding: 0px; +} +.w2ui-list ul li { + float: left; + margin: 2px 1px 0px 2px; + border-radius: 3px; + width: auto; + padding: 3px 10px 1px 7px; + border: 1px solid #88b0d6; + background-color: #eff3f5; + white-space: nowrap; + cursor: default; + font-family: verdana; + font-size: 11px; + line-height: 100%; + height: 20px; + overflow: hidden; + text-overflow: ellipsis; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-list ul li:hover { + background-color: #d0dbe1; +} +.w2ui-list ul li:last-child { + border-radius: 0px; + border: 1px solid transparent; + background-color: transparent; +} +.w2ui-list ul li:last-child input { + padding: 1px; + padding-top: 0px; + margin: 0px; + border: 0px; + outline: none; + height: auto; + line-height: 100%; + font-size: inherit; + font-family: inherit; + background-color: transparent; +} +.w2ui-list ul li .w2ui-list-remove { + float: right; + width: 15px; + height: 14px; + margin: -1px -9px 0px 3px; + border-radius: 15px; +} +.w2ui-list ul li .w2ui-list-remove:hover { + background-color: #D77F7F; + color: white; +} +.w2ui-list ul li .w2ui-list-remove:before { + position: relative; + top: 0px; + padding: 0px; + margin: 0px; + left: 5px; + color: inherit; + opacity: 0.7; + text-shadow: inherit; + font-size: inherit; + font-variant: small-caps; + content: 'x'; + line-height: 100%; +} +.w2ui-list ul li > span.file-size { + pointer-events: none; + color: #777; +} +.w2ui-list .w2ui-enum-placeholder { + display: inline; + position: absolute; + pointer-events: none; + color: #999; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-list.w2ui-file-dragover { + background-color: #E4FFDA; + border: 1px solid #93E07D; +} +/************************************************* +* ---- Layout ---- +*/ +.w2ui-layout { + overflow: hidden !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-layout * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-layout > div { + position: absolute; + overflow: hidden; + border: 0px; + margin: 0px; + padding: 0px; + outline: 0px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-layout > div .w2ui-panel { + display: none; + position: absolute; + z-index: 120; +} +.w2ui-layout > div .w2ui-panel .w2ui-panel-title { + position: absolute; + left: 0px; + top: 0px; + right: 0px; + padding: 5px; + background-image: -webkit-linear-gradient(#dae6f3, #c2d5ed); + background-image: -moz-linear-gradient(#dae6f3, #c2d5ed); + background-image: -ms-linear-gradient(#dae6f3, #c2d5ed); + background-image: -o-linear-gradient(#dae6f3, #c2d5ed); + background-image: linear-gradient(#dae6f3, #c2d5ed); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffdae6f3', endColorstr='#ffc2d5ed', GradientType=0); + border: 1px solid #b9cee9; + border-bottom: 1px solid #99bbe8; +} +.w2ui-layout > div .w2ui-panel .w2ui-panel-tabs { + position: absolute; + left: 0px; + top: 0px; + right: 0px; + z-index: 2; + display: none; + overflow: hidden; + background-color: #fafafa; + padding: 4px 0px; +} +.w2ui-layout > div .w2ui-panel .w2ui-panel-tabs > .w2ui-tab.active { + background-color: #f2f2f2; +} +.w2ui-layout > div .w2ui-panel .w2ui-panel-toolbar { + position: absolute; + left: 0px; + top: 0px; + right: 0px; + z-index: 2; + display: none; + overflow: hidden; + background-color: #fafafa; + border-bottom: 1px solid silver; + padding: 4px; +} +.w2ui-layout > div .w2ui-panel .w2ui-panel-content { + position: absolute; + left: 0px; + top: 0px; + right: 0px; + bottom: 0px; + z-index: 1; + color: inherit; + background-color: #f2f2f2; +} +.w2ui-layout > div .w2ui-resizer { + display: none; + position: absolute; + z-index: 121; + background-color: transparent; +} +.w2ui-layout > div .w2ui-resizer:hover, +.w2ui-layout > div .w2ui-resizer.active { + background-color: #c8cad1; +} +/************************************************* +* ---- Grid ---- +*/ +.w2ui-grid { + position: relative; + border: 1px solid #c0c0c0; + border-radius: 2px; + overflow: hidden !important; +} +.w2ui-grid > div { + position: absolute; + overflow: hidden; +} +.w2ui-grid .w2ui-grid-header { + position: absolute; + border-bottom: 1px solid #99bbe8 !important; + height: 28px; + overflow: hidden; + color: #444444; + font-size: 13px; + text-align: center; + padding: 7px; + background-image: -webkit-linear-gradient(#dae6f3, #c2d5ed); + background-image: -moz-linear-gradient(#dae6f3, #c2d5ed); + background-image: -ms-linear-gradient(#dae6f3, #c2d5ed); + background-image: -o-linear-gradient(#dae6f3, #c2d5ed); + background-image: linear-gradient(#dae6f3, #c2d5ed); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffdae6f3', endColorstr='#ffc2d5ed', GradientType=0); + border-top-left-radius: 2px; + border-top-right-radius: 2px; +} +.w2ui-grid .w2ui-grid-toolbar { + position: absolute; + border-bottom: 1px solid #c0c0c0; + background-color: #eaeaea; + height: 38px; + padding: 6px 1px 4px 1px; + margin: 0px; + box-shadow: 0px 1px 2px #dddddd; +} +.w2ui-grid .w2ui-toolbar-search { + width: 160px; + margin-right: 3px; +} +.w2ui-grid .w2ui-toolbar-search .w2ui-search-all { + outline: none !important; + width: 160px !important; + border-radius: 3px !important; + line-height: normal !important; + height: 23px !important; + border: 1px solid #b9b9b9 !important; + color: #000000 !important; + background-color: #ffffff !important; + padding: 3px 18px 3px 21px !important; + margin: 0px !important; + margin-top: 1px !important; +} +.w2ui-grid .w2ui-toolbar-search .w2ui-search-down { + position: absolute; + margin-top: -7px; + margin-left: 4px; +} +.w2ui-grid .w2ui-toolbar-search .w2ui-search-clear { + position: absolute; + width: 16px; + height: 16px; + margin-top: -8px; + margin-left: -20px; + border-radius: 15px; + cursor: default; +} +.w2ui-grid .w2ui-toolbar-search .w2ui-search-clear:hover { + background-color: #D77F7F; + color: white; +} +.w2ui-grid .w2ui-toolbar-search .w2ui-search-clear:before { + position: relative; + top: 2px; + left: 5px; + opacity: 0.6; + color: inherit; + text-shadow: inherit; + content: 'x'; + cursor: default; +} +.w2ui-grid .w2ui-grid-body { + position: absolute; + overflow: hidden; + padding: 0px; + background-color: #ffffff; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +.w2ui-grid .w2ui-grid-body input, +.w2ui-grid .w2ui-grid-body select, +.w2ui-grid .w2ui-grid-body textarea { + user-select: text; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + -o-user-select: text; +} +.w2ui-grid .w2ui-grid-body div.w2ui-input { + user-select: tex; + -webkit-user-select: tex; + -moz-user-select: tex; + -ms-user-select: tex; + -o-user-select: tex; + background-color: white; + padding: 4px 2px; + border: 1px solid transparent; + width: 100%; + height: 100%; + pointer-events: auto; + outline: none; + white-space: pre; + overflow: hidden; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-columns, +.w2ui-grid .w2ui-grid-body .w2ui-grid-fcolumns { + overflow: hidden; + position: absolute; + left: 0px; + top: 0px; + right: 0px; + box-shadow: 0px 1px 4px #dddddd; + height: auto; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-columns table, +.w2ui-grid .w2ui-grid-body .w2ui-grid-fcolumns table { + height: auto; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-columns .w2ui-resizer, +.w2ui-grid .w2ui-grid-body .w2ui-grid-fcolumns .w2ui-resizer { + position: absolute; + z-index: 1000; + display: block; + background-image: none; + background-color: rgba(0, 0, 0, 0); + /* needed for IE */ + padding: 0px; + margin: 0px; + width: 6px; + height: 12px; + cursor: col-resize; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords { + position: absolute; + left: 0px; + right: 0px; + top: 0px; + bottom: 0px; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd { + color: inherit; + background-color: #ffffff; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd:hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd:hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd.w2ui-record-hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd.w2ui-record-hover { + color: inherit; + background-color: #e6f0ff; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd.w2ui-empty-record:hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd.w2ui-empty-record:hover { + background-color: #ffffff; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even { + color: inherit; + background-color: #f3f6fa; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even:hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even:hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even.w2ui-record-hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even.w2ui-record-hover { + color: inherit; + background-color: #e6f0ff; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even.w2ui-empty-record:hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even.w2ui-empty-record:hover { + background-color: #f3f6fa; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-selected, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-selected, +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr td.w2ui-selected, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr td.w2ui-selected { + color: #000000 !important; + background-color: #b6d5ff !important; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-inactive, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-inactive, +.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr td.w2ui-inactive, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr td.w2ui-inactive { + background-color: #d8dee7 !important; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-expanded1, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-expanded1 { + height: 0px; + border-bottom: 1px solid #b2bac0; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-expanded1 > div, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-expanded1 > div { + height: 0px; + border: 0px; + transition: height .3s, opacity .3s; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-expanded2, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-expanded2 { + height: 0px; + border-radius: 0px; + border-bottom: 1px solid #b2bac0; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-expanded2 > div, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-expanded2 > div { + height: 0px; + border: 0px; + transition: height .3s, opacity .3s; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-load-more, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-load-more { + border-top: 1px solid #d6d5d7; + cursor: pointer; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-load-more > div, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-load-more > div { + text-align: center; + color: #777777; + background-color: rgba(233, 237, 243, 0.5); + padding: 10px 0px 15px 0px; + border-top: 1px solid #ffffff; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-load-more > div:hover, +.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-load-more > div:hover { + color: inherit; + background-color: #e6f0ff; +} +.w2ui-grid .w2ui-grid-body table { + border-spacing: 0px; + border-collapse: collapse; + table-layout: fixed; + width: 1px; +} +.w2ui-grid .w2ui-grid-body table .w2ui-head { + margin: 0px; + padding: 0px; + border-right: 1px solid #c5c5c5; + border-bottom: 1px solid #c5c5c5; + color: #000000; + background-image: -webkit-linear-gradient(#f9f9f9, #e4e4e4); + background-image: -moz-linear-gradient(#f9f9f9, #e4e4e4); + background-image: -ms-linear-gradient(#f9f9f9, #e4e4e4); + background-image: -o-linear-gradient(#f9f9f9, #e4e4e4); + background-image: linear-gradient(#f9f9f9, #e4e4e4); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#ffe4e4e4', GradientType=0); +} +.w2ui-grid .w2ui-grid-body table .w2ui-head > div { + padding: 7px 3px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + position: relative; +} +.w2ui-grid .w2ui-grid-body table .w2ui-head.w2ui-col-intersection { + border-right-color: #72b2ff; +} +.w2ui-grid .w2ui-grid-body table .w2ui-head.w2ui-reorder-cols-head:hover { + cursor: move; +} +.w2ui-grid .w2ui-grid-body table .w2ui-head .col-intersection-marker { + padding: 0; + position: absolute; + height: 100%; + top: 0; +} +.w2ui-grid .w2ui-grid-body table .w2ui-head .col-intersection-marker.left { + left: 0; + margin-left: -5px; +} +.w2ui-grid .w2ui-grid-body table .w2ui-head .col-intersection-marker.right { + right: 0; + margin-right: -5px; +} +.w2ui-grid .w2ui-grid-body table .w2ui-head .col-intersection-marker .top-marker { + position: absolute; + top: 0; + height: 0; + width: 0; + border-top: 5px solid #72b2ff; + border-left: 5px solid transparent; + border-right: 5px solid transparent; +} +.w2ui-grid .w2ui-grid-body table .w2ui-head .col-intersection-marker .bottom-marker { + position: absolute; + bottom: 0; + height: 0; + width: 0; + border-bottom: 5px solid #72b2ff; + border-left: 5px solid transparent; + border-right: 5px solid transparent; +} +.w2ui-grid .w2ui-grid-body table td { + border-right: 1px solid #d6d5d7; + border-bottom: 0px solid #d6d5d7; + cursor: default; + overflow: hidden; +} +.w2ui-grid .w2ui-grid-body table td.w2ui-soft-span, +.w2ui-grid .w2ui-grid-body table td.w2ui-soft-hidden { + border-right-color: transparent; +} +.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data { + margin: 0px; + padding: 0px; +} +.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data .w2ui-info { + position: relative; + top: 1px; + font-size: 14px; + color: #8D99A7; + cursor: pointer; + width: 16px; + display: inline-block; + margin-right: 2px; + text-align: center; +} +.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data > div { + padding: 3px 3px 3px 3px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data > div.flexible-record { + height: auto; + overflow: visible; + white-space: normal; +} +.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data .w2ui-show-children { + width: 16px; + height: 10px; + display: inline-block; + position: relative; + top: -1px; + cursor: pointer; +} +.w2ui-grid .w2ui-grid-body table td:last-child { + border-right: 0px; +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-number { + width: 34px; + color: #777777; + background-color: rgba(233, 237, 243, 0.5); +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-number div { + padding: 0px 7px 0px 3px; + text-align: right; +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-number.w2ui-head { + cursor: pointer; +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-select { + width: 26px; +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-select div { + padding: 0px 0px; + text-align: center; + overflow: hidden; +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-select div input[type=checkbox] { + margin-top: 0px; + margin-bottom: 0px; + position: relative; +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-expand { + width: 26px; +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-expand div { + padding: 0px 0px; + text-align: center; + font-weight: bold; +} +.w2ui-grid .w2ui-grid-body table .w2ui-col-selected { + background-color: #d1d1d1 !important; +} +.w2ui-grid .w2ui-grid-body table .w2ui-row-selected { + background-color: #d1d1d1 !important; +} +.w2ui-grid .w2ui-grid-body div.w2ui-col-header { + height: auto !important; + width: 100%; + overflow: hidden; + padding-right: 10px !important; +} +.w2ui-grid .w2ui-grid-body div.w2ui-col-header > div.w2ui-sort-up { + border: 4px solid transparent; + border-bottom: 5px solid #8D99A7; + margin-top: -2px; + margin-right: -7px; + float: right; +} +.w2ui-grid .w2ui-grid-body div.w2ui-col-header > div.w2ui-sort-down { + border: 4px solid transparent; + border-top: 5px solid #8D99A7; + margin-top: 2px; + margin-right: -7px; + float: right; +} +.w2ui-grid .w2ui-grid-body .w2ui-col-group { + text-align: center; +} +.w2ui-grid .w2ui-grid-body .w2ui-grid-scroll1 { + position: absolute; + left: 0px; + bottom: 0px; + border-top: 1px solid #ddd; + border-right: 1px solid #ddd; + background-color: #FAFAFA; +} +.w2ui-grid .w2ui-grid-empty-msg { + position: absolute; + top: 27px; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255, 255, 255, 0.65); +} +.w2ui-grid .w2ui-grid-empty-msg > div { + position: absolute; + left: 0; + right: 0; + top: 45%; + transform: translateY(-45%); + text-align: center; + font-size: 13px; + color: #666; +} +.w2ui-grid .w2ui-changed { + background: url(data:image/gif;base64,R0lGODlhCgAKAJEAALAABf///wAAAAAAACH5BAEAAAIALAAAAAAKAAoAAAIPlI8Hy8mbxIsSUnup3rQAADs=) no-repeat top right; +} +.w2ui-grid .w2ui-edit-box { + position: absolute; + z-index: 1001; + border: 2px solid #6299DA; + pointer-events: auto; +} +.w2ui-grid .w2ui-editable { + overflow: hidden; + height: 100% !important; + margin: 0px !important; + padding: 0px !important; +} +.w2ui-grid .w2ui-editable input { + border: 0px; + border-radius: 0px; + margin: 0px; + padding: 4px 3px; + width: 100%; + height: 100%; +} +.w2ui-grid .w2ui-editable input.w2ui-select { + outline: none !important; + background: #fff; +} +.w2ui-grid .w2ui-grid-summary { + position: absolute; + box-shadow: 0px -1px 4px #aaaaaa; +} +.w2ui-grid .w2ui-grid-summary table { + color: inherit; +} +.w2ui-grid .w2ui-grid-summary table .w2ui-odd { + background-color: #eef5eb; +} +.w2ui-grid .w2ui-grid-summary table .w2ui-even { + background-color: #f8fff5; +} +.w2ui-grid .w2ui-grid-footer { + position: absolute; + margin: 0px; + padding: 0px; + text-align: center; + height: 24px; + overflow: hidden; + user-select: text; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + -o-user-select: text; + box-shadow: 0px -1px 4px #eeeeee; + color: #444444; + background-color: #f8f8f8; + border-top: 1px solid #dddddd; + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; +} +.w2ui-grid .w2ui-grid-footer .w2ui-footer-left { + float: left; + padding-top: 5px; + padding-left: 5px; +} +.w2ui-grid .w2ui-grid-footer .w2ui-footer-right { + float: right; + padding-top: 5px; + padding-right: 5px; +} +.w2ui-grid .w2ui-grid-footer .w2ui-footer-center { + padding: 2px; + text-align: center; +} +.w2ui-grid .w2ui-grid-footer .w2ui-footer-center .w2ui-footer-nav { + width: 110px; + margin: 0 auto; + padding: 0px; + text-align: center; +} +.w2ui-grid .w2ui-grid-footer .w2ui-footer-center .w2ui-footer-nav input[type=text] { + padding: 1px 2px 2px 2px; + border-radius: 3px; + width: 40px; + text-align: center; +} +.w2ui-grid .w2ui-grid-footer .w2ui-footer-center .w2ui-footer-nav a.w2ui-footer-btn { + display: inline-block; + border-radius: 3px; + cursor: pointer; + font-size: 11px; + line-height: 16px; + padding: 1px 5px; + width: 30px; + height: 18px; + margin-top: -1px; + color: #000000; + background-color: transparent; +} +.w2ui-grid .w2ui-grid-footer .w2ui-footer-center .w2ui-footer-nav a.w2ui-footer-btn:hover { + color: #000000; + background-color: #aec8ff; +} +.w2ui-grid .w2ui-grid-focus-input { + position: absolute; + top: 0; + right: 0; + z-index: -1; + opacity: 0; + overflow: hidden; + padding: 0px; + margin: 0px; + width: 1px; + height: 1px; + resize: none; + border: 0px; +} +/* SpeadSheet */ +.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr td.w2ui-selected { + background-color: #EEF4FE !important; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr td.w2ui-inactive { + background-color: #F4F6F9 !important; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-records table td { + border-right-width: 1px; + border-bottom: 1px solid #efefef; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd, +.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even, +.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd:hover, +.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even:hover { + background-color: inherit; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr:first-child td { + border-top: 0px; + border-bottom: 0px; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr td.w2ui-selected { + background-color: #EEF4FE !important; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr td.w2ui-inactive { + background-color: #F4F6F9 !important; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table td { + border-right-width: 1px; + border-bottom: 1px solid #efefef; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd, +.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even, +.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd:hover, +.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even:hover { + background-color: inherit; +} +.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr:first-child td { + border-bottom: 0px; +} +.w2ui-ss .w2ui-grid-body .w2ui-selection { + position: absolute; + z-index: 1000; + border: 2px solid #6299DA; + /* #457FC2; */ + pointer-events: none; +} +.w2ui-ss .w2ui-grid-body .w2ui-selection .w2ui-selection-resizer { + cursor: crosshair; + position: absolute; + bottom: 0px; + right: 0px; + width: 6px; + height: 6px; + margin-right: -3px; + margin-bottom: -3px; + background-color: #457FC2; + border: 0.5px solid #fff; + outline: 1px solid white; + pointer-events: auto; +} +.w2ui-ss .w2ui-grid-body .w2ui-selection.w2ui-inactive { + border: 2px solid #C0C2C5; +} +.w2ui-ss .w2ui-grid-body .w2ui-selection.w2ui-inactive .w2ui-selection-resizer { + background-color: #B0B0B0; +} +.w2ui-ss .w2ui-grid-body .w2ui-soft-range { + position: absolute; + pointer-events: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.w2ui-ss .w2ui-grid-body .w2ui-changed { + background: inherit; + /* do not show changed for spreadsheet */ +} +.w2ui-info-bubble table { + font-size: 11px; + font-family: Verdana, Arial, sans-serif; + color: white; + text-shadow: 1px 1px solid #999; +} +.w2ui-info-bubble table tr td:first-child { + white-space: nowrap; + padding: 2px; + padding-right: 10px; + color: #ddd; + vertical-align: top; +} +.w2ui-info-bubble table tr td:last-child { + white-space: pre; + padding: 2px; +} +.w2ui-overlay .w2ui-select-field { + padding: 4px 0px; + cursor: default; +} +.w2ui-overlay .w2ui-select-field table { + font-size: 11px; + font-family: Verdana, Arial, sans-serif; + border-spacing: 0px; + border-collapse: border-collapse; +} +.w2ui-overlay .w2ui-select-field table tr { + height: 27px; +} +.w2ui-overlay .w2ui-select-field table tr:hover { + background-color: #b6d5ff; +} +.w2ui-overlay .w2ui-select-field table tr td:nth-child(1) { + width: 26px; + padding-right: 6px; + text-align: right; + color: #888; +} +.w2ui-overlay .w2ui-select-field table tr td:nth-child(2) { + padding: 3px 20px 3px 0px; +} +.w2ui-overlay .w2ui-col-on-off { + padding: 4px 0px; +} +.w2ui-overlay .w2ui-col-on-off table { + border-spacing: 0px; + border-collapse: border-collapse; +} +.w2ui-overlay .w2ui-col-on-off table tr:hover { + background-color: #b6d5ff; +} +.w2ui-overlay .w2ui-col-on-off table td input[type=checkbox] { + margin: 3px 2px 2px 2px; +} +.w2ui-overlay .w2ui-col-on-off table td label { + display: block; + padding: 3px 0px; + padding-right: 10px; +} +.w2ui-overlay .w2ui-col-on-off table td:first-child { + padding: 4px 0px 4px 6px; +} +.w2ui-overlay .w2ui-col-on-off table td:last-child { + padding: 4px 6px 4px 0px; +} +.w2ui-overlay .w2ui-grid-searches { + text-align: left; + padding: 0px; + border-top: 0px; + background-color: #f7f6f0; +} +.w2ui-overlay .w2ui-grid-searches table { + padding: 4px; + padding-top: 12px; + border-collapse: border-collapse; +} +.w2ui-overlay .w2ui-grid-searches table td { + padding: 4px; + /* for IE */ +} +.w2ui-overlay .w2ui-grid-searches table td.close-btn { + width: 20px; + padding-right: 20px; +} +.w2ui-overlay .w2ui-grid-searches table td.close-btn button { + min-width: 24px; + height: 24px; + padding-top: 5px !important; +} +.w2ui-overlay .w2ui-grid-searches table td.caption { + text-align: right; + padding-right: 5px; + border-right: 1px solid #e8e8e3; +} +.w2ui-overlay .w2ui-grid-searches table td.operator { + text-align: left; + padding: 0px 10px; + padding-right: 5px; + border-right: 1px solid #e8e8e3; + height: 31px; +} +.w2ui-overlay .w2ui-grid-searches table td.operator select { + width: 100%; + color: black; +} +.w2ui-overlay .w2ui-grid-searches table td.operator select::-ms-expand { + display: none; +} +.w2ui-overlay .w2ui-grid-searches table td.value { + padding-right: 5px; + padding-left: 5px; +} +.w2ui-overlay .w2ui-grid-searches table td.value input[type=text] { + border-radius: 3px; + padding: 3px; + margin-right: 3px; + height: 23px; +} +.w2ui-overlay .w2ui-grid-searches table td.value select { + padding: 3px; + margin-right: 3px; + height: 23px; +} +.w2ui-overlay .w2ui-grid-searches table td.actions { + border-right: 0px; +} +.w2ui-overlay .w2ui-grid-searches table td.actions > div { + margin: -7px; + margin-top: 15px; + padding: 13px 0px; + text-align: center; + background-color: #efefe9; + border-top: 1px solid #e8e8e3; +} +/************************************************* +* ---- Popup ---- +*/ +.w2ui-popup { + position: fixed; + z-index: 1600; + overflow: hidden; + font-family: Verdana, Arial, sans-serif; + border-radius: 6px; + padding: 0px; + margin: 0px; + border: 1px solid #777777; + background-color: #eeeeee; + box-shadow: 0px 0px 25px #555555; +} +.w2ui-popup, +.w2ui-popup * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-popup .w2ui-popup-title { + padding: 6px; + border-radius: 6px 6px 0px 0px; + background-image: -webkit-linear-gradient(#ececec, #dfdfdf); + background-image: -moz-linear-gradient(#ececec, #dfdfdf); + background-image: -ms-linear-gradient(#ececec, #dfdfdf); + background-image: -o-linear-gradient(#ececec, #dfdfdf); + background-image: linear-gradient(#ececec, #dfdfdf); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffececec', endColorstr='#ffdfdfdf', GradientType=0); + border-bottom: 2px solid #bfbfbf; + position: absolute; + overflow: hidden; + height: 32px; + left: 0px; + right: 0px; + top: 0px; + text-overflow: ellipsis; + text-align: center; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + cursor: move; + font-size: 15px; + color: #555555; + z-index: 300; +} +.w2ui-popup .w2ui-popup-button { + float: right; + width: 18px; + height: 18px; + cursor: pointer; + overflow: hidden; + padding: 0px; + margin: 0px 3px 0px 0px; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAQCAYAAABQrvyxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAj1JREFUeNrslr9rFFEQxz/zZi/qxSgW2lsqkiYoBku5Ro1o4UFKEYkgSaxSCLYqdv5IEVPYCMJJwERWrK0CKhoQ8hdobQTjXW7njcXlYnLunQQu0YDTLOy+Nzvfme98Z8Td2ckW2OGWdMvRvYfT/RGfBPoBBVpLK0AEPgVkdGL06vt/CoB5nBaRE8AXYKXNsQIwaB4fAwOtH+88mn4m7ifN4vUYebWBKkFKqjIV3N9NjI2Uuw5ARI45fBanH+F77iFnN8JHETmS68P9NHBQNTwHL8foaSN4SqoyA/SZyL4tqQAQBVYCLOFYlNxmq0WorVLpN9Oe5LKt1CsgRVWpAOfB66phBuhTkepSdfnKVjaxNJMSWn/iawmTtpeDp6pWBpaBoqrMqoYU6AOqIbFhxGa3R4V8nfNNKLUESzXJhoCvQC+wF/gW1C5IiC+2XUbD5jA3rd4C26NR3945IA2iRzqRJgdElJJlSQocAKrAD2A/6Ev3cLajjN59MDWHyKl2voOI1zKbv3Xj2lCHJFoz+LXuBoIAjnUklEvJrDDT5LwmdhG8blkyBxRjXSu4loE0X4VEznXKV3SnoOFMB7YUolBcbcKNdxuPXUBPu8pbLXsK0ghebVjEXgNoYmXLtGLuxd6ePU+AQ20AaIrb4DpFycmSv81/7YsiMgAstB1kQgE47O4LuQmCNwGOB7VxCb/URsRSTbhkmU4ifGiZHd1Z5m7fnxoIQSaBo39YJRZj9LGb4yPzXWm1/9voX7afAwAC5tacDTA2XgAAAABJRU5ErkJggg==) no-repeat center left; + background-position: 0px 0px; + color: transparent !important; + border-radius: 3px; + border: 1px solid transparent; +} +.w2ui-popup .w2ui-popup-close { + margin-top: 0px; + background-position: -32px 0px; +} +.w2ui-popup .w2ui-popup-close:hover { + background-color: #cccccc; + border: 1px solid #aaaaaa; +} +.w2ui-popup .w2ui-popup-max { + background-position: -16px 0px; +} +.w2ui-popup .w2ui-popup-max:hover { + background-color: #cccccc; + border: 1px solid #aaaaaa; +} +.w2ui-popup .w2ui-box, +.w2ui-popup .w2ui-box-temp { + position: absolute; + left: 0px; + right: 0px; + top: 32px; + bottom: 52px; + z-index: 100; +} +.w2ui-popup .w2ui-popup-body { + font-size: 12px; + line-height: 130%; + padding: 0px 7px 7px 7px; + color: #000000; + background-color: #eeeeee; + position: absolute; + overflow: auto; + width: 100%; + height: 100%; +} +.w2ui-popup .w2ui-popup-buttons { + padding: 12px; + border-radius: 0px 0px 6px 6px; + border-top: 1px solid #d5d8d8; + background-color: #f1f1f1; + text-align: center; + position: absolute; + overflow: hidden; + height: 52px; + left: 0px; + right: 0px; + bottom: 0px; + z-index: 200; +} +.w2ui-popup .w2ui-popup-no-title { + border-top-left-radius: 6px; + border-top-right-radius: 6px; + top: 0px !important; +} +.w2ui-popup .w2ui-popup-no-buttons { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + bottom: 0px !important; +} +.w2ui-popup .w2ui-alert-msg, +.w2ui-popup .w2ui-confirm-msg { + font-size: 13px; + line-height: 1.5; +} +/************************************************* +* ---- Sidebar ---- +*/ +.w2ui-sidebar { + position: relative; + cursor: default; + overflow: hidden !important; + background-color: #edf1f6 !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-sidebar * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-sidebar > div { + position: absolute; + overflow: hidden; +} +.w2ui-sidebar .w2ui-sidebar-top { + position: absolute; + z-index: 2; + top: 0px; + left: 0px; + right: 0px; +} +.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-left, +.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-right { + position: absolute; + right: 2px; + top: 2px; + height: 24px; + padding: 5px; + border-radius: 2px; + background-size: 16px 12px; + background-position: center center; + background-repeat: no-repeat; + background-color: #edf1f6; +} +.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-left:hover, +.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-right:hover { + background-color: #d7e1ef; +} +.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-left { + left: auto; + width: 25px; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAzklEQVR4Ae2THRDEMBCFzy1ucatb3eJ2uhi3uNUtbnGrW9zi1rOdNzdvdl7nDpvYt/9/r7+/51myZZf/zXkD2iMHHRSb0x3oskwMieK05PwEXqP4ExSL0wp0ROao2OOuMPOMdUL6XU1/oGLcFWb+NqyTd2W/P/2qTr9h+nFXhOkHXRHiNyjrgp/U/V+WaQcaNY13zZI0A1JvcVqAnrGDTdtDtZUHjHIJhxxVLN0iqXgCP1l/7h8U9kc6abyJ4/eNWPpGdBv+XdUK0K8cnvcBly2rDr7C1HQAAAAASUVORK5CYII='); +} +.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-right { + left: 2px; + width: auto; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAz0lEQVR4Ae2UG7TGMBCEr1vd4la3uMUtuli3utWtbnGLW9zi9l/bDMzJG7u12cfJfLunf1+UEC9Bv0vVQwJ8hjRCaZafflb1C9RQf4OD0gSDE+i+PiJAabFhQc1y1AYYsJGLY3lgxM17uWPO56yPiFDqVPWgRtpIHSd1zPnwkBsdI58OlNwx4fP2X0TgfMTOoHSdKOXkpyNvEyQh7ul+4swxJSTQuwNDxz68l/ukVNbu0Neen5Z+KvzWxBAqHds349uPFJ/jVOrPjxUq++OLf+20q5+noXo0AAAAAElFTkSuQmCC'); +} +.w2ui-sidebar .w2ui-sidebar-bottom { + position: absolute; + z-index: 2; + bottom: 0px; + left: 0px; + right: 0px; +} +.w2ui-sidebar .w2ui-sidebar-div { + position: absolute; + z-index: 1; + overflow: auto; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + padding: 2px 0px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +.w2ui-sidebar .w2ui-sidebar-div table { + width: 100%; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node { + background-color: #edf1f6; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + margin: 0px; + padding: 1px 0px; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node table { + pointer-events: none; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node .w2ui-node-caption, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node .w2ui-node-image, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node .w2ui-node-image > span, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node td.w2ui-node-dots { + color: #000000; + text-shadow: 0px 0px 0px #ffffff; + pointer-events: none; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node .w2ui-node-caption:hover, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node .w2ui-node-image:hover, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node .w2ui-node-image > span:hover, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node td.w2ui-node-dots:hover { + color: inherit; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node:hover { + border-top: 1px solid #f9f9f9; + border-bottom: 1px solid #f9f9f9; + background-color: #d7e1ef; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node .w2ui-node-image { + width: 22px; + text-align: center; + pointer-events: none; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node .w2ui-node-image > span { + color: #516173 !important; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node input, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node button { + pointer-events: auto; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected:hover { + position: relative; + background-image: -webkit-linear-gradient(#69b1e0, #4a96d3); + background-image: -moz-linear-gradient(#69b1e0, #4a96d3); + background-image: -ms-linear-gradient(#69b1e0, #4a96d3); + background-image: -o-linear-gradient(#69b1e0, #4a96d3); + background-image: linear-gradient(#69b1e0, #4a96d3); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff69b1e0', endColorstr='#ff4a96d3', GradientType=0); + border-top: 1px solid #5295cd; + border-bottom: 1px solid #2661a6; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected .w2ui-node-caption, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected:hover .w2ui-node-caption, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected .w2ui-node-image, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected:hover .w2ui-node-image, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected .w2ui-node-image > span, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected:hover .w2ui-node-image > span, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected td.w2ui-node-dots, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected:hover td.w2ui-node-dots { + color: #ffffff !important; + text-shadow: 1px 1px 2px #666666 !important; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected:before { + content: ""; + border: 1px dashed #eee; + border-radius: 3px; + position: absolute; + top: 2px; + bottom: 2px; + left: 2px; + right: 2px; + pointer-events: none; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-selected.w2ui-inactive:before { + border: 1px dashed transparent !important; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled:hover { + background: transparent !important; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled .w2ui-node-caption, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled:hover .w2ui-node-caption, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled .w2ui-node-image, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled:hover .w2ui-node-image, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled .w2ui-node-image > span, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled:hover .w2ui-node-image > span, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled td.w2ui-node-dots, +.w2ui-sidebar .w2ui-sidebar-div .w2ui-disabled:hover td.w2ui-node-dots { + opacity: 0.4; + filter: alpha(opacity=40); + color: #000000 !important; + text-shadow: 0px 0px 0px #ffffff !important; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-caption { + white-space: nowrap; + padding: 5px 0px 5px 3px; + margin: 1px 0px 1px 22px; + position: relative; + z-index: 1; + font-size: 12px; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-group { + white-space: nowrap; + overflow: hidden; + padding: 10px 0px 10px 10px; + margin: 0px; + cursor: default; + color: #868b92; + background-color: transparent; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-group :nth-child(1) { + /* show / hide link */ + margin-right: 10px; + float: right; + color: transparent; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-group :nth-child(2) { + /* title text */ + font-weight: normal; + text-transform: uppercase; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-sub { + overflow: hidden; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-flat { + padding: 6px 0px; + text-align: center; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-flat .w2ui-node-image { + text-align: center; + width: auto; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-flat .w2ui-node-image > span { + font-size: 16px; + color: #000000; + text-shadow: 0px 0px 0px #ffffff; +} +.w2ui-sidebar .w2ui-sidebar-div .w2ui-node-flat .w2ui-node-image.w2ui-icon { + width: 21px; +} +.w2ui-sidebar .w2ui-sidebar-div td.w2ui-node-dots { + width: 18px; + padding: 0px 0px 1px 7px; + text-align: center; +} +.w2ui-sidebar .w2ui-sidebar-div td.w2ui-node-dots .w2ui-expand { + width: 16px; + margin-top: -3px; + pointer-events: auto; +} +.w2ui-sidebar .w2ui-sidebar-div td.w2ui-node-data { + padding: 1px 1px 3px 1px; +} +.w2ui-sidebar .w2ui-sidebar-div td.w2ui-node-data .w2ui-node-image { + padding: 3px 0px 0px 0px; + float: left; +} +.w2ui-sidebar .w2ui-sidebar-div td.w2ui-node-data .w2ui-node-image > span { + font-size: 16px; + color: #000000; + text-shadow: 0px 0px 0px #ffffff; +} +.w2ui-sidebar .w2ui-sidebar-div td.w2ui-node-data .w2ui-node-image.w2ui-icon { + margin-top: 3px; +} +.w2ui-sidebar .w2ui-sidebar-div td.w2ui-node-data .w2ui-node-count { + float: right; + border: 1px solid #6f9dc7; + border-radius: 20px; + width: auto; + height: 18px; + padding: 2px 7px; + margin: 3px 4px -2px 0; + background-color: #e7f0fc; + color: #667274; + box-shadow: 0 0 0px #ffffff; + text-shadow: 1px 1px 1px #e6e6e6; + position: relative; + z-index: 2; +} +/************************************************* +* ---- Tabs ---- +*/ +.w2ui-tabs { + cursor: default; + overflow: hidden !important; + position: relative; + background-color: #fafafa; + padding: 3px 0px; +} +.w2ui-tabs:not(.w2ui-tabs-up) { + padding-bottom: 0px !important; +} +.w2ui-tabs.w2ui-tabs-up { + padding-top: 0px !important; +} +.w2ui-tabs table { + border-bottom: 1px solid silver; + padding: 0px 7px; +} +.w2ui-tabs .w2ui-tab { + padding: 6px 20px; + text-align: center; + color: #000000; + background-color: transparent; + border: 1px solid #c0c0c0; + border-bottom: 1px solid silver; + white-space: nowrap; + margin: 1px 1px -1px 0px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +.w2ui-tabs .w2ui-tab.active { + color: #000000; + background-color: #ffffff; + border: 1px solid #c0c0c0; + border-bottom: 1px solid transparent; +} +.w2ui-tabs .w2ui-tab.closable { + padding: 6px 28px 6px 20px; +} +.w2ui-tabs .w2ui-tab-close { + color: #555; + text-shadow: 1px 1px 1px #bbb; + float: right; + margin: 6px 4px 0px 0px; + padding: 0px 0px 0px 5px; + width: 16px; + height: 16px; + opacity: 0.9; + border: 0px; + border-top: 3px solid transparent; + border-radius: 9px; +} +.w2ui-tabs .w2ui-tab-close:hover { + background-color: #D77F7F; + color: white; +} +.w2ui-tabs .w2ui-tab-close:before { + position: relative; + top: -2px; + left: 0px; + opacity: 0.6; + color: inherit; + text-shadow: inherit; + content: 'x'; +} +.w2ui-tabs.w2ui-tabs-up table { + border-top: 1px solid #c0c0c0; + border-bottom: 0px; +} +.w2ui-tabs.w2ui-tabs-up .w2ui-tab { + border-top: 1px solid #C0C0C0; + margin: -1px 1px 0px 0px; + border-radius: 0px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} +.w2ui-tabs.w2ui-tabs-up .w2ui-tab.active { + border: 1px solid #c0c0c0; + border-top: 1px solid transparent; +} +.w2ui-tabs.w2ui-tabs-up .w2ui-tab-close { + margin-top: 4px; +} +/************************************************* +* ---- Toolbar ---- +*/ +.w2ui-toolbar { + margin: 0px; + padding: 2px; + outline: 0px; + position: relative; + background-color: #efefef; + overflow: hidden !important; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +.w2ui-toolbar .disabled { + opacity: 0.3; + filter: alpha(opacity=30); +} +.w2ui-toolbar table { + table-layout: auto !important; +} +.w2ui-toolbar table td { + border: 0px !important; +} +.w2ui-toolbar table.w2ui-button { + margin: 0 1px 0 0; + border-radius: 4px; + height: 24px; + min-width: 24px; + border: 1px solid transparent; + background-color: transparent; +} +.w2ui-toolbar table.w2ui-button .w2ui-tb-image { + width: 22px; + height: 16px; + padding: 0; + margin: 5px 1px 3px 1px!important; + border: 0!important; + text-align: center; +} +.w2ui-toolbar table.w2ui-button .w2ui-tb-image > span { + font-size: 15px; + display: block; + color: #8d99a7; +} +.w2ui-toolbar table.w2ui-button .w2ui-tb-image > span:before { + vertical-align: top !important; +} +.w2ui-toolbar table.w2ui-button .w2ui-tb-caption { + color: #000000; + padding: 0px 4px 0px 2px; +} +.w2ui-toolbar table.w2ui-button .w2ui-tb-count { + padding: 0px 3px 0px 1px; +} +.w2ui-toolbar table.w2ui-button .w2ui-tb-count > span { + border: 1px solid #f6fcf4; + border-radius: 11px; + width: auto; + height: 18px; + padding: 0px 6px 1px 6px; + background-color: #f2f8f0; + color: #666666; + box-shadow: 0px 0px 2px #474545; + text-shadow: 1px 1px 0px #ffffff; +} +.w2ui-toolbar table.w2ui-button .w2ui-tb-down { + padding: 1px 3px 1px 1px; +} +.w2ui-toolbar table.w2ui-button .w2ui-tb-down > div { + border: 4px solid transparent; + border-top: 5px solid #8D99A7; + margin-top: 5px; +} +.w2ui-toolbar table.w2ui-button.over { + border: 1px solid #cccccc; + background-color: #eeeeee; +} +.w2ui-toolbar table.w2ui-button.over .w2ui-tb-caption { + color: #000000; +} +.w2ui-toolbar table.w2ui-button.down { + border: 1px solid #aaaaaa; + background-color: #dddddd; +} +.w2ui-toolbar table.w2ui-button.down .w2ui-tb-caption { + color: #666666; +} +.w2ui-toolbar table.w2ui-button.checked { + border: 1px solid #aaaaaa; + background-color: #ffffff; +} +.w2ui-toolbar table.w2ui-button.checked .w2ui-tb-caption { + color: #000000; +} +.w2ui-toolbar table.w2ui-button table { + height: 17px; + border-radius: 4px; + cursor: default; +} +.w2ui-toolbar .w2ui-break { + background-image: -webkit-linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, #999999 40%, #999999 60%, rgba(153, 153, 153, 0.1) 100%); + background-image: -moz-linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, #999999 40%, #999999 60%, rgba(153, 153, 153, 0.1) 100%); + background-image: -ms-linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, #999999 40%, #999999 60%, rgba(153, 153, 153, 0.1) 100%); + background-image: -o-linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, #999999 40%, #999999 60%, rgba(153, 153, 153, 0.1) 100%); + background-image: linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, #999999 40%, #999999 60%, rgba(153, 153, 153, 0.1) 100%); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff999999', endColorstr='#ff999999', GradientType=0); + width: 1px !important; + height: 22px; + padding: 0px; + margin: 0px 6px; +} +.w2ui-listview { + overflow: auto !important; + background-color: #ffffff !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-listview * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} +.w2ui-listview > ul { + list-style-type: none; + margin: 0; + cursor: default; +} +.w2ui-listview > ul > li { + display: inline-block; + vertical-align: top; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + border: 1px solid transparent; + border-radius: 4px; +} +.w2ui-listview > ul > li.w2ui-focused { + border: 1px solid #2661a6; +} +.w2ui-listview > ul > li.w2ui-selected { + border: 1px solid #2661a6; +} +.w2ui-listview > ul > li.w2ui-selected, +.w2ui-listview > ul > li.w2ui-selected.hover { + background-image: -webkit-linear-gradient(#69b1e0, #4a96d3); + background-image: -moz-linear-gradient(#69b1e0, #4a96d3); + background-image: -ms-linear-gradient(#69b1e0, #4a96d3); + background-image: -o-linear-gradient(#69b1e0, #4a96d3); + background-image: linear-gradient(#69b1e0, #4a96d3); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff69b1e0', endColorstr='#ff4a96d3', GradientType=0); +} +.w2ui-listview > ul > li.w2ui-selected > div > div.caption, +.w2ui-listview > ul > li.w2ui-selected.hover > div > div.caption { + color: #ffffff; +} +.w2ui-listview > ul > li.w2ui-selected > div > div.description, +.w2ui-listview > ul > li.w2ui-selected.hover > div > div.description { + color: #dddddd; +} +.w2ui-listview > ul > li.w2ui-selected > div > div.extra > div > div, +.w2ui-listview > ul > li.w2ui-selected.hover > div > div.extra > div > div { + color: #dddddd; +} +.w2ui-listview > ul > li.hover { + background-color: #d7e1ef; + border: 1px solid #2661a6; +} +.w2ui-listview > ul > li div { + vertical-align: middle; +} +.w2ui-listview > ul > li > div > div.caption { + display: block; + text-align: center; + word-wrap: break-word; + max-height: 50px; + color: #000000; + font-size: 12px; +} +.w2ui-listview > ul > li > div > div.description { + display: none; + text-align: left; + color: #777777; + font-size: 12px; +} +.w2ui-listview > ul > li > div > div.extra { + display: none; +} +.w2ui-listview > ul > li > div > div.extra > div > div { + color: #777777; +} +.w2ui-icon-small > ul { + padding: 1px 0px 0px 1px; +} +.w2ui-icon-small > ul > li { + margin: 0px 1px 1px 0px; + padding: 2px; + width: 250px; + white-space: nowrap; +} +.w2ui-icon-small > ul > li > div > div.w2ui-listview-img { + display: inline-block; + width: 26px; + height: 22px; + font-size: 21px; + margin-right: 2px; +} +.w2ui-icon-small > ul > li > div > div.caption { + display: inline-block; +} +.w2ui-icon-medium > ul { + padding: 4px 0px 0px 4px; +} +.w2ui-icon-medium > ul > li { + margin: 0px 4px 4px 0px; + padding: 4px; + width: 100px; +} +.w2ui-icon-medium > ul > li > div > div.w2ui-listview-img { + display: block; + width: 92px; + height: 60px; + font-size: 57px; + margin-left: auto; + margin-right: auto; + background-position: center; +} +.w2ui-icon-large > ul { + padding: 4px 0px 0px 4px; +} +.w2ui-icon-large > ul > li { + margin: 0px 4px 4px 0px; + padding: 4px; + width: 160px; +} +.w2ui-icon-large > ul > li > div > div.w2ui-listview-img { + display: block; + width: 152px; + height: 120px; + font-size: 114px; + margin-left: auto; + margin-right: auto; + background-position: center; +} +.w2ui-icon-tile > ul { + padding: 1px 0px 0px 1px; +} +.w2ui-icon-tile > ul > li { + margin: 0px 1px 1px 0px; + padding: 4px; + width: 250px; + white-space: nowrap; +} +.w2ui-icon-tile > ul > li > div > div.w2ui-listview-img { + display: inline-block; + width: 72px; + height: 60px; + font-size: 57px; + float: left; + margin-right: 4px; +} +.w2ui-icon-tile > ul > li > div > div.caption { + text-align: left; +} +.w2ui-icon-tile > ul > li > div > div.description { + display: block; +} +.w2ui-table > ul { + padding: 0; +} +.w2ui-table > ul > li { + width: 100%; + padding: 2px; + border-radius: 0px; + border-bottom: 1px dotted lightgray; +} +.w2ui-table > ul > li > div { + display: inline-block; + position: relative; + width: 100%; + white-space: nowrap; + overflow: hidden; +} +.w2ui-table > ul > li > div > div.w2ui-listview-img { + display: inline-block; + width: 38px; + height: 32px; + font-size: 31px; + margin-right: 2px; +} +.w2ui-table > ul > li > div > div.caption { + display: inline-block; +} +.w2ui-table > ul > li > div > div.extra { + display: inline-block; + position: absolute; + right: 0; + height: 100%; + background-color: #ffffff; +} +.w2ui-table > ul > li > div > div.extra > div:before { + display: inline-block; + height: 100%; + width: 0; + content: ''; + vertical-align: middle; +} +.w2ui-table > ul > li > div > div.extra > div { + display: inline; +} +.w2ui-table > ul > li > div > div.extra > div > div { + display: inline-block; + font-size: 12px; +} +.w2ui-table > ul > li.w2ui-selected div.extra, +.w2ui-table > ul > li.w2ui-selected.hover div.extra { + background-image: -webkit-linear-gradient(#69b1e0, #4a96d3); + background-image: -moz-linear-gradient(#69b1e0, #4a96d3); + background-image: -ms-linear-gradient(#69b1e0, #4a96d3); + background-image: -o-linear-gradient(#69b1e0, #4a96d3); + background-image: linear-gradient(#69b1e0, #4a96d3); + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff69b1e0', endColorstr='#ff4a96d3', GradientType=0); +} +.w2ui-table > ul > li.hover div.extra { + background-color: #d7e1ef; +} +.w2ui-listview > ul > li div.icon-none { + border: 1px solid rgba(102, 102, 102, 0.35); +} diff --git a/lib/w2ui-1.5.rc1.js b/lib/w2ui-1.5.rc1.js new file mode 100644 index 00000000..89f54de6 --- /dev/null +++ b/lib/w2ui-1.5.rc1.js @@ -0,0 +1,18953 @@ +/* w2ui 1.5.rc1 (nightly) (c) http://w2ui.com, vitmalina@gmail.com */ +var w2ui = w2ui || {}; +var w2obj = w2obj || {}; // expose object to be able to overwrite default functions + +/************************************************ +* Library: Web 2.0 UI for jQuery +* - Following objects are defines +* - w2ui - object that will contain all widgets +* - w2obj - object with widget prototypes +* - w2utils - basic utilities +* - $().w2render - common render +* - $().w2destroy - common destroy +* - $().w2marker - marker plugin +* - $().w2tag - tag plugin +* - $().w2overlay - overlay plugin +* - $().w2menu - menu plugin +* - w2utils.event - generic event object +* - Dependencies: jQuery +* +* == NICE TO HAVE == +* - overlay should be displayed where more space (on top or on bottom) +* - write and article how to replace certain framework functions +* - add maxHeight for the w2menu +* - add time zone +* - TEST On IOS +* - $().w2marker() -- only unmarks first instance +* - subitems for w2menus() +* - add w2utils.lang wrap for all captions in all buttons. +* - $().w2date(), $().w2dateTime() +* +************************************************/ + +var w2utils = (function ($) { + var tmp = {}; // for some temp variables + var obj = { + version : '1.5.RC1', + settings : { + "locale" : "en-us", + "dateFormat" : "m/d/yyyy", + "timeFormat" : "hh:mi pm", + "datetimeFormat" : "m/d/yyyy|hh:mi pm", + "currencyPrefix" : "$", + "currencySuffix" : "", + "currencyPrecision" : 2, + "groupSymbol" : ",", + "decimalSymbol" : ".", + "shortmonths" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + "fullmonths" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + "shortdays" : ["M", "T", "W", "T", "F", "S", "S"], + "fulldays" : ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], + "weekStarts" : "M", // can be "M" for Monday or "S" for Sunday + "dataType" : 'HTTPJSON', // can be HTTP, HTTPJSON, RESTFULL, RESTFULLJSON, JSON (case sensitive) + "phrases" : {}, // empty object for english phrases + "dateStartYear" : 1950, // start year for date-picker + "dateEndYear" : 2020 // end year for date picker + }, + isBin : isBin, + isInt : isInt, + isFloat : isFloat, + isMoney : isMoney, + isHex : isHex, + isAlphaNumeric : isAlphaNumeric, + isEmail : isEmail, + isDate : isDate, + isTime : isTime, + isDateTime : isDateTime, + age : age, + interval : interval, + date : date, + formatSize : formatSize, + formatNumber : formatNumber, + formatDate : formatDate, + formatTime : formatTime, + formatDateTime : formatDateTime, + stripTags : stripTags, + encodeTags : encodeTags, + decodeTags : decodeTags, + escapeId : escapeId, + base64encode : base64encode, + base64decode : base64decode, + md5 : md5, + transition : transition, + lock : lock, + unlock : unlock, + message : message, + lang : lang, + locale : locale, + getSize : getSize, + getStrWidth : getStrWidth, + scrollBarSize : scrollBarSize, + checkName : checkName, + checkUniqueId : checkUniqueId, + parseRoute : parseRoute, + cssPrefix : cssPrefix, + getCursorPosition : getCursorPosition, + setCursorPosition : setCursorPosition, + testLocalStorage : testLocalStorage, + hasLocalStorage : testLocalStorage(), + // some internal variables + isIOS : ((navigator.userAgent.toLowerCase().indexOf('iphone') != -1 || + navigator.userAgent.toLowerCase().indexOf('ipod') != -1 || + navigator.userAgent.toLowerCase().indexOf('ipad') != -1) + ? true : false), + isIE : ((navigator.userAgent.toLowerCase().indexOf('msie') != -1 || + navigator.userAgent.toLowerCase().indexOf('trident') != -1 ) + ? true : false) + }; + return obj; + + function isBin (val) { + var re = /^[0-1]+$/; + return re.test(val); + } + + function isInt (val) { + var re = /^[-+]?[0-9]+$/; + return re.test(val); + } + + function isFloat (val) { + if (typeof val == 'string') val = val.replace(/\s+/g, '').replace(w2utils.settings.groupSymbol, '').replace(w2utils.settings.decimalSymbol, '.'); + return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val)); + } + + function isMoney (val) { + var se = w2utils.settings; + var re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') + + '[-+]?'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') + + '[0-9]*[\\'+ se.decimalSymbol +']?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i'); + if (typeof val === 'string') { + val = val.replace(new RegExp(se.groupSymbol, 'g'), ''); + } + if (typeof val === 'object' || val === '') return false; + return re.test(val); + } + + function isHex (val) { + var re = /^[a-fA-F0-9]+$/; + return re.test(val); + } + + function isAlphaNumeric (val) { + var re = /^[a-zA-Z0-9_-]+$/; + return re.test(val); + } + + function isEmail (val) { + var email = /^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; + return email.test(val); + } + + function isDate (val, format, retDate) { + if (!val) return false; + + var dt = 'Invalid Date'; + var month, day, year; + + if (format == null) format = w2utils.settings.dateFormat; + + if (typeof val.getUTCFullYear === 'function') { // date object + year = val.getUTCFullYear(); + month = val.getUTCMonth() + 1; + day = val.getUTCDate(); + } else if (parseInt(val) == val && parseInt(val) > 0) { + val = new Date(parseInt(val)); + year = val.getUTCFullYear(); + month = val.getUTCMonth() + 1; + day = val.getUTCDate(); + } else { + val = String(val); + // convert month formats + if (new RegExp('mon', 'ig').test(format)) { + format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); + val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); + for (var m = 0, len = w2utils.settings.fullmonths.length; m < len; m++) { + var t = w2utils.settings.fullmonths[m]; + val = val.replace(new RegExp(t, 'ig'), (parseInt(m) + 1)).replace(new RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1)); + } + } + // format date + var tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/'); + var tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase(); + if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } + if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } + if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } + if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } + if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } + if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } + if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } + } + if (!isInt(year)) return false; + if (!isInt(month)) return false; + if (!isInt(day)) return false; + year = +year; + month = +month; + day = +day; + dt = new Date(year, month - 1, day); + // do checks + if (month == null) return false; + if (String(dt) == 'Invalid Date') return false; + if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false; + if (retDate === true) return dt; else return true; + } + + function isTime (val, retTime) { + // Both formats 10:20pm and 22:20 + if (val == null) return false; + var max, am, pm; + // -- process american format + val = String(val); + val = val.toUpperCase(); + am = val.indexOf('AM') >= 0; + pm = val.indexOf('PM') >= 0; + var ampm = (pm || am); + if (ampm) max = 12; else max = 24; + val = val.replace('AM', '').replace('PM', ''); + val = $.trim(val); + // --- + var tmp = val.split(':'); + var h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0), s = parseInt(tmp[2] || 0); + // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT: + if ((!ampm || tmp.length !== 1) && tmp.length !== 2 && tmp.length !== 3) { return false; } + if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false; } + if (tmp.length > 1 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false; } + if (tmp.length > 2 && (tmp[2] === '' || s < 0 || s > 59 || !this.isInt(tmp[2]) || tmp[2].length !== 2)) { return false; } + // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00). + // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are. + if (!ampm && max === h && (m !== 0 || s !== 0)) { return false; } + if (ampm && tmp.length === 1 && h === 0) { return false; } + + if (retTime === true) { + if (pm && h !== 12) h += 12; // 12:00pm - is noon + if (am && h === 12) h += 12; // 12:00am - is midnight + return { + hours: h, + minutes: m, + seconds: s + }; + } + return true; + } + + function isDateTime (val, format, retDate) { + if (format == null) format = w2utils.settings.datetimeFormat; + var formats = format.split('|'); + if (typeof val.getUTCFullYear === 'function') { // date object + if (retDate !== true) return true; + return val; + } else if (parseInt(val) == val && parseInt(val) > 0) { + val = new Date(parseInt(val)); + if (retDate !== true) return true; + return val; + } else { + var tmp = String(val).indexOf(' '); + var values = [val.substr(0, tmp), val.substr(tmp).trim()]; + formats[0] = formats[0].trim(); + if (formats[1]) formats[1] = formats[1].trim(); + // check + var tmp1 = w2utils.isDate(values[0], formats[0], true); + var tmp2 = w2utils.isTime(values[1], true); + if (tmp1 !== false && tmp2 !== false) { + if (retDate !== true) return true; + tmp1.setHours(tmp2.hours); + tmp1.setMinutes(tmp2.minutes); + tmp1.setSeconds(tmp2.seconds); + return tmp1; + } else { + return false; + } + } + } + + function age(dateStr) { + var d1; + if (dateStr === '' || dateStr == null) return ''; + if (typeof dateStr.getUTCFullYear === 'function') { // date object + d1 = dateStr; + } else if (parseInt(dateStr) == dateStr && parseInt(dateStr) > 0) { + d1 = new Date(parseInt(dateStr)); + } else { + d1 = new Date(dateStr); + } + if (String(d1) == 'Invalid Date') return ''; + + var d2 = new Date(); + var sec = (d2.getTime() - d1.getTime()) / 1000; + var amount = ''; + var type = ''; + if (sec < 0) { + amount = 0; + type = 'sec'; + } else if (sec < 60) { + amount = Math.floor(sec); + type = 'sec'; + if (sec < 0) { amount = 0; type = 'sec'; } + } else if (sec < 60*60) { + amount = Math.floor(sec/60); + type = 'min'; + } else if (sec < 24*60*60) { + amount = Math.floor(sec/60/60); + type = 'hour'; + } else if (sec < 30*24*60*60) { + amount = Math.floor(sec/24/60/60); + type = 'day'; + } else if (sec < 365*24*60*60) { + amount = Math.floor(sec/30/24/60/60*10)/10; + type = 'month'; + } else if (sec < 365*4*24*60*60) { + amount = Math.floor(sec/365/24/60/60*10)/10; + type = 'year'; + } else if (sec >= 365*4*24*60*60) { + // factor in leap year shift (only older then 4 years) + amount = Math.floor(sec/365.25/24/60/60*10)/10; + type = 'year'; + } + return amount + ' ' + type + (amount > 1 ? 's' : ''); + } + + function interval (value) { + var ret = ''; + if (value < 1000) { + ret = "< 1 sec"; + } else if (value < 60000) { + ret = Math.floor(value / 1000) + " secs"; + } else if (value < 3600000) { + ret = Math.floor(value / 60000) + " mins"; + } else if (value < 86400000) { + ret = Math.floor(value / 3600000 * 10) / 10 + " hours"; + } else if (value < 2628000000) { + ret = Math.floor(value / 86400000 * 10) / 10 + " days"; + } else if (value < 3.1536e+10) { + ret = Math.floor(value / 2628000000 * 10) / 10 + " months"; + } else { + ret = Math.floor(value / 3.1536e+9) / 10 + " years"; + } + return ret; + } + + function date (dateStr) { + if (dateStr === '' || dateStr == null || (typeof dateStr == 'object' && !dateStr.getMonth)) return ''; + var d1 = new Date(dateStr); + if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps + if (String(d1) == 'Invalid Date') return ''; + + var months = w2utils.settings.shortmonths; + var d2 = new Date(); // today + var d3 = new Date(); + d3.setTime(d3.getTime() - 86400000); // yesterday + + var dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear(); + var dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear(); + var dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear(); + + var time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); + var time2= (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); + var dsp = dd1; + if (dd1 === dd2) dsp = time; + if (dd1 === dd3) dsp = w2utils.lang('Yesterday'); + + return ''+ dsp +''; + } + + function formatSize (sizeStr) { + if (!w2utils.isFloat(sizeStr) || sizeStr === '') return ''; + sizeStr = parseFloat(sizeStr); + if (sizeStr === 0) return 0; + var sizes = ['Bt', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB']; + var i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) ); + return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + (sizes[i] || '??'); + } + + function formatNumber (val, fraction, useGrouping) { + if (val == null || val === '' || typeof val == 'object') return ''; + var options = { + minimumFractionDigits : fraction, + maximumFractionDigits : fraction, + useGrouping : useGrouping + }; + if (fraction == null || fraction < 0) { + options.minimumFractionDigits = 0; + options.maximumFractionDigits = 20; + } + return parseFloat(val).toLocaleString(w2utils.settings.locale, options); + } + + function formatDate (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + if (!format) format = this.settings.dateFormat; + if (dateStr === '' || dateStr == null || (typeof dateStr == 'object' && !dateStr.getMonth)) return ''; + + var dt = new Date(dateStr); + if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps + if (String(dt) == 'Invalid Date') return ''; + + var year = dt.getFullYear(); + var month = dt.getMonth(); + var date = dt.getDate(); + return format.toLowerCase() + .replace('month', w2utils.settings.fullmonths[month]) + .replace('mon', w2utils.settings.shortmonths[month]) + .replace(/yyyy/g, year) + .replace(/yyy/g, year) + .replace(/yy/g, year > 2000 ? 100 + parseInt(String(year).substr(2)) : String(year).substr(2)) + .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceded by a letter + .replace(/mm/g, (month + 1 < 10 ? '0' : '') + (month + 1)) + .replace(/dd/g, (date < 10 ? '0' : '') + date) + .replace(/th/g, (date == 1 ? 'st' : 'th')) + .replace(/th/g, (date == 2 ? 'nd' : 'th')) + .replace(/th/g, (date == 3 ? 'rd' : 'th')) + .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceded by a letter + .replace(/(^|[^a-z$])d/g, '$1' + date); // only y's that are not preceded by a letter + } + + function formatTime (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + var months = w2utils.settings.shortmonths; + var fullMonths = w2utils.settings.fullmonths; + if (!format) format = this.settings.timeFormat; + if (dateStr === '' || dateStr == null || (typeof dateStr == 'object' && !dateStr.getMonth)) return ''; + + var dt = new Date(dateStr); + if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps + if (w2utils.isTime(dateStr)) { + var tmp = w2utils.isTime(dateStr, true); + dt = new Date(); + dt.setHours(tmp.hours); + dt.setMinutes(tmp.minutes); + } + if (String(dt) == 'Invalid Date') return ''; + + var type = 'am'; + var hour = dt.getHours(); + var h24 = dt.getHours(); + var min = dt.getMinutes(); + var sec = dt.getSeconds(); + if (min < 10) min = '0' + min; + if (sec < 10) sec = '0' + sec; + if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) { + if (hour >= 12) type = 'pm'; + if (hour > 12) hour = hour - 12; + } + return format.toLowerCase() + .replace('am', type) + .replace('pm', type) + .replace('hhh', (hour < 10 ? '0' + hour : hour)) + .replace('hh24', (h24 < 10 ? '0' + h24 : h24)) + .replace('h24', h24) + .replace('hh', hour) + .replace('mm', min) + .replace('mi', min) + .replace('ss', sec) + .replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceded by a letter + .replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceded by a letter + .replace(/(^|[^a-z$])s/g, '$1' + sec); // only y's that are not preceded by a letter + } + + function formatDateTime(dateStr, format) { + var fmt; + if (dateStr === '' || dateStr == null || (typeof dateStr == 'object' && !dateStr.getMonth)) return ''; + if (typeof format !== 'string') { + fmt = [this.settings.dateFormat, this.settings.timeFormat]; + } else { + fmt = format.split('|'); + fmt[0] = fmt[0].trim(); + fmt[1] = fmt[1].trim(); + } + // older formats support + if (fmt[1] == 'h12') fmt[1] = 'h:m pm'; + if (fmt[1] == 'h24') fmt[1] = 'h24:m'; + return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]); + } + + function stripTags (html) { + if (html == null) return html; + switch (typeof html) { + case 'number': + break; + case 'string': + html = String(html).replace(/(<([^>]+)>)/ig, ""); + break; + case 'object': + // does not modify original object, but creates a copy + if (Array.isArray(html)) { + html = $.extend(true, [], html); + for (var i = 0; i < html.length; i++) html[i] = this.stripTags(html[i]); + } else { + html = $.extend(true, {}, html); + for (var i in html) html[i] = this.stripTags(html[i]); + } + break; + } + return html; + } + + function encodeTags (html) { + if (html == null) return html; + switch (typeof html) { + case 'number': + break; + case 'string': + html = String(html).replace(/&/g, "&").replace(/>/g, ">").replace(/").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&"); + break; + case 'object': + // does not modify original object, but creates a copy + if (Array.isArray(html)) { + html = $.extend(true, [], html); + for (var i = 0; i < html.length; i++) html[i] = this.decodeTags(html[i]); + } else { + html = $.extend(true, {}, html); + for (var i in html) html[i] = this.decodeTags(html[i]); + } + break; + } + return html; + } + + function escapeId (id) { + if (id === '' || id == null) return ''; + return String(id).replace(/([;&,\.\+\*\~'`:"\!\^#$%@\[\]\(\)=<>\|\/? {}\\])/g, '\\$1'); + } + + function base64encode (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + input = utf8_encode(input); + + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); + } + + function utf8_encode (string) { + string = String(string).replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + return utftext; + } + + return output; + } + + function base64decode (input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + output = output + String.fromCharCode(chr1); + if (enc3 !== 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 !== 64) { + output = output + String.fromCharCode(chr3); + } + } + output = utf8_decode(output); + + function utf8_decode (utftext) { + var string = ""; + var i = 0; + var c = 0, c2, c3; + + while ( i < utftext.length ) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + + return string; + } + + return output; + } + + function md5(input) { + /* + * Based on http://pajhome.org.uk/crypt/md5 + */ + + var hexcase = 0; + var b64pad = ""; + + function __pj_crypt_hex_md5(s) { + return __pj_crypt_rstr2hex(__pj_crypt_rstr_md5(__pj_crypt_str2rstr_utf8(s))); + } + function __pj_crypt_b64_md5(s) { + return __pj_crypt_rstr2b64(__pj_crypt_rstr_md5(__pj_crypt_str2rstr_utf8(s))); + } + function __pj_crypt_any_md5(s, e) { + return __pj_crypt_rstr2any(__pj_crypt_rstr_md5(__pj_crypt_str2rstr_utf8(s)), e); + } + function __pj_crypt_hex_hmac_md5(k, d) + { + return __pj_crypt_rstr2hex(__pj_crypt_rstr_hmac_md5(__pj_crypt_str2rstr_utf8(k), __pj_crypt_str2rstr_utf8(d))); + } + function __pj_crypt_b64_hmac_md5(k, d) + { + return __pj_crypt_rstr2b64(__pj_crypt_rstr_hmac_md5(__pj_crypt_str2rstr_utf8(k), __pj_crypt_str2rstr_utf8(d))); + } + function __pj_crypt_any_hmac_md5(k, d, e) + { + return __pj_crypt_rstr2any(__pj_crypt_rstr_hmac_md5(__pj_crypt_str2rstr_utf8(k), __pj_crypt_str2rstr_utf8(d)), e); + } + + /* + * Calculate the MD5 of a raw string + */ + function __pj_crypt_rstr_md5(s) + { + return __pj_crypt_binl2rstr(__pj_crypt_binl_md5(__pj_crypt_rstr2binl(s), s.length * 8)); + } + + /* + * Calculate the HMAC-MD5, of a key and some data (raw strings) + */ + function __pj_crypt_rstr_hmac_md5(key, data) + { + var bkey = __pj_crypt_rstr2binl(key); + if (bkey.length > 16) + bkey = __pj_crypt_binl_md5(bkey, key.length * 8); + + var ipad = Array(16), opad = Array(16); + for (var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = __pj_crypt_binl_md5(ipad.concat(__pj_crypt_rstr2binl(data)), 512 + data.length * 8); + return __pj_crypt_binl2rstr(__pj_crypt_binl_md5(opad.concat(hash), 512 + 128)); + } + + /* + * Convert a raw string to a hex string + */ + function __pj_crypt_rstr2hex(input) + { + try { + hexcase + } catch (e) { + hexcase = 0; + } + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var output = ""; + var x; + for (var i = 0; i < input.length; i++) + { + x = input.charCodeAt(i); + output += hex_tab.charAt((x >>> 4) & 0x0F) + + hex_tab.charAt(x & 0x0F); + } + return output; + } + + /* + * Convert a raw string to a base-64 string + */ + function __pj_crypt_rstr2b64(input) + { + try { + b64pad + } catch (e) { + b64pad = ''; + } + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var output = ""; + var len = input.length; + for (var i = 0; i < len; i += 3) + { + var triplet = (input.charCodeAt(i) << 16) + | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) + | (i + 2 < len ? input.charCodeAt(i + 2) : 0); + for (var j = 0; j < 4; j++) + { + if (i * 8 + j * 6 > input.length * 8) + output += b64pad; + else + output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F); + } + } + return output; + } + + /* + * Convert a raw string to an arbitrary string encoding + */ + function __pj_crypt_rstr2any(input, encoding) + { + var divisor = encoding.length; + var i, j, q, x, quotient; + + /* Convert to an array of 16-bit big-endian values, forming the dividend */ + var dividend = Array(Math.ceil(input.length / 2)); + for (i = 0; i < dividend.length; i++) + { + dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); + } + + /* + * Repeatedly perform a long division. The binary array forms the dividend, + * the length of the encoding is the divisor. Once computed, the quotient + * forms the dividend for the next step. All remainders are stored for later + * use. + */ + var full_length = Math.ceil(input.length * 8 / + (Math.log(encoding.length) / Math.log(2))); + var remainders = Array(full_length); + for (j = 0; j < full_length; j++) + { + quotient = Array(); + x = 0; + for (i = 0; i < dividend.length; i++) + { + x = (x << 16) + dividend[i]; + q = Math.floor(x / divisor); + x -= q * divisor; + if (quotient.length > 0 || q > 0) + quotient[quotient.length] = q; + } + remainders[j] = x; + dividend = quotient; + } + + /* Convert the remainders to the output string */ + var output = ""; + for (i = remainders.length - 1; i >= 0; i--) + output += encoding.charAt(remainders[i]); + + return output; + } + + /* + * Encode a string as utf-8. + * For efficiency, this assumes the input is valid utf-16. + */ + function __pj_crypt_str2rstr_utf8(input) + { + var output = ""; + var i = -1; + var x, y; + + while (++i < input.length) + { + /* Decode utf-16 surrogate pairs */ + x = input.charCodeAt(i); + y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; + if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) + { + x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); + i++; + } + + /* Encode output as utf-8 */ + if (x <= 0x7F) + output += String.fromCharCode(x); + else if (x <= 0x7FF) + output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), + 0x80 | (x & 0x3F)); + else if (x <= 0xFFFF) + output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), + 0x80 | ((x >>> 6) & 0x3F), + 0x80 | (x & 0x3F)); + else if (x <= 0x1FFFFF) + output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), + 0x80 | ((x >>> 12) & 0x3F), + 0x80 | ((x >>> 6) & 0x3F), + 0x80 | (x & 0x3F)); + } + return output; + } + + /* + * Encode a string as utf-16 + */ + function __pj_crypt_str2rstr_utf16le(input) + { + var output = ""; + for (var i = 0; i < input.length; i++) + output += String.fromCharCode(input.charCodeAt(i) & 0xFF, + (input.charCodeAt(i) >>> 8) & 0xFF); + return output; + } + + function __pj_crypt_str2rstr_utf16be(input) + { + var output = ""; + for (var i = 0; i < input.length; i++) + output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, + input.charCodeAt(i) & 0xFF); + return output; + } + + /* + * Convert a raw string to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ + function __pj_crypt_rstr2binl(input) + { + var output = Array(input.length >> 2); + for (var i = 0; i < output.length; i++) + output[i] = 0; + for (var i = 0; i < input.length * 8; i += 8) + output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); + return output; + } + + /* + * Convert an array of little-endian words to a string + */ + function __pj_crypt_binl2rstr(input) + { + var output = ""; + for (var i = 0; i < input.length * 32; i += 8) + output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); + return output; + } + + /* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ + function __pj_crypt_binl_md5(x, len) + { + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for (var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = __pj_crypt_md5_ff(a, b, c, d, x[i + 0], 7, -680876936); + d = __pj_crypt_md5_ff(d, a, b, c, x[i + 1], 12, -389564586); + c = __pj_crypt_md5_ff(c, d, a, b, x[i + 2], 17, 606105819); + b = __pj_crypt_md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = __pj_crypt_md5_ff(a, b, c, d, x[i + 4], 7, -176418897); + d = __pj_crypt_md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = __pj_crypt_md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = __pj_crypt_md5_ff(b, c, d, a, x[i + 7], 22, -45705983); + a = __pj_crypt_md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = __pj_crypt_md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = __pj_crypt_md5_ff(c, d, a, b, x[i + 10], 17, -42063); + b = __pj_crypt_md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = __pj_crypt_md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = __pj_crypt_md5_ff(d, a, b, c, x[i + 13], 12, -40341101); + c = __pj_crypt_md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = __pj_crypt_md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); + + a = __pj_crypt_md5_gg(a, b, c, d, x[i + 1], 5, -165796510); + d = __pj_crypt_md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = __pj_crypt_md5_gg(c, d, a, b, x[i + 11], 14, 643717713); + b = __pj_crypt_md5_gg(b, c, d, a, x[i + 0], 20, -373897302); + a = __pj_crypt_md5_gg(a, b, c, d, x[i + 5], 5, -701558691); + d = __pj_crypt_md5_gg(d, a, b, c, x[i + 10], 9, 38016083); + c = __pj_crypt_md5_gg(c, d, a, b, x[i + 15], 14, -660478335); + b = __pj_crypt_md5_gg(b, c, d, a, x[i + 4], 20, -405537848); + a = __pj_crypt_md5_gg(a, b, c, d, x[i + 9], 5, 568446438); + d = __pj_crypt_md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = __pj_crypt_md5_gg(c, d, a, b, x[i + 3], 14, -187363961); + b = __pj_crypt_md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = __pj_crypt_md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = __pj_crypt_md5_gg(d, a, b, c, x[i + 2], 9, -51403784); + c = __pj_crypt_md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = __pj_crypt_md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); + + a = __pj_crypt_md5_hh(a, b, c, d, x[i + 5], 4, -378558); + d = __pj_crypt_md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = __pj_crypt_md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = __pj_crypt_md5_hh(b, c, d, a, x[i + 14], 23, -35309556); + a = __pj_crypt_md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = __pj_crypt_md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = __pj_crypt_md5_hh(c, d, a, b, x[i + 7], 16, -155497632); + b = __pj_crypt_md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = __pj_crypt_md5_hh(a, b, c, d, x[i + 13], 4, 681279174); + d = __pj_crypt_md5_hh(d, a, b, c, x[i + 0], 11, -358537222); + c = __pj_crypt_md5_hh(c, d, a, b, x[i + 3], 16, -722521979); + b = __pj_crypt_md5_hh(b, c, d, a, x[i + 6], 23, 76029189); + a = __pj_crypt_md5_hh(a, b, c, d, x[i + 9], 4, -640364487); + d = __pj_crypt_md5_hh(d, a, b, c, x[i + 12], 11, -421815835); + c = __pj_crypt_md5_hh(c, d, a, b, x[i + 15], 16, 530742520); + b = __pj_crypt_md5_hh(b, c, d, a, x[i + 2], 23, -995338651); + + a = __pj_crypt_md5_ii(a, b, c, d, x[i + 0], 6, -198630844); + d = __pj_crypt_md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = __pj_crypt_md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = __pj_crypt_md5_ii(b, c, d, a, x[i + 5], 21, -57434055); + a = __pj_crypt_md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = __pj_crypt_md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = __pj_crypt_md5_ii(c, d, a, b, x[i + 10], 15, -1051523); + b = __pj_crypt_md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = __pj_crypt_md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = __pj_crypt_md5_ii(d, a, b, c, x[i + 15], 10, -30611744); + c = __pj_crypt_md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = __pj_crypt_md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = __pj_crypt_md5_ii(a, b, c, d, x[i + 4], 6, -145523070); + d = __pj_crypt_md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = __pj_crypt_md5_ii(c, d, a, b, x[i + 2], 15, 718787259); + b = __pj_crypt_md5_ii(b, c, d, a, x[i + 9], 21, -343485551); + + a = __pj_crypt_safe_add(a, olda); + b = __pj_crypt_safe_add(b, oldb); + c = __pj_crypt_safe_add(c, oldc); + d = __pj_crypt_safe_add(d, oldd); + } + return Array(a, b, c, d); + } + + /* + * These functions implement the four basic operations the algorithm uses. + */ + function __pj_crypt_md5_cmn(q, a, b, x, s, t) + { + return __pj_crypt_safe_add(__pj_crypt_bit_rol(__pj_crypt_safe_add(__pj_crypt_safe_add(a, q), __pj_crypt_safe_add(x, t)), s), b); + } + function __pj_crypt_md5_ff(a, b, c, d, x, s, t) + { + return __pj_crypt_md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); + } + function __pj_crypt_md5_gg(a, b, c, d, x, s, t) + { + return __pj_crypt_md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); + } + function __pj_crypt_md5_hh(a, b, c, d, x, s, t) + { + return __pj_crypt_md5_cmn(b ^ c ^ d, a, b, x, s, t); + } + function __pj_crypt_md5_ii(a, b, c, d, x, s, t) + { + return __pj_crypt_md5_cmn(c ^ (b | (~d)), a, b, x, s, t); + } + + /* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + function __pj_crypt_safe_add(x, y) + { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + } + + /* + * Bitwise rotate a 32-bit number to the left. + */ + function __pj_crypt_bit_rol(num, cnt) + { + return (num << cnt) | (num >>> (32 - cnt)); + } + + return __pj_crypt_hex_md5(input); + + } + + function transition (div_old, div_new, type, callBack) { + var width = $(div_old).width(); + var height = $(div_old).height(); + var time = 0.5; + + if (!div_old || !div_new) { + console.log('ERROR: Cannot do transition when one of the divs is null'); + return; + } + + div_old.parentNode.style.cssText += 'perspective: 900px; overflow: hidden;'; + div_old.style.cssText += '; position: absolute; z-index: 1019; backface-visibility: hidden'; + div_new.style.cssText += '; position: absolute; z-index: 1020; backface-visibility: hidden'; + + switch (type) { + case 'slide-left': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'; + div_new.style.cssText += 'overflow: hidden; transform: translate3d('+ width + 'px, 0, 0)'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)'; + div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(-'+ width +'px, 0, 0)'; + }, 1); + break; + + case 'slide-right': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'; + div_new.style.cssText += 'overflow: hidden; transform: translate3d(-'+ width +'px, 0, 0)'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0px, 0, 0)'; + div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d('+ width +'px, 0, 0)'; + }, 1); + break; + + case 'slide-down': + // init divs + div_old.style.cssText += 'overflow: hidden; z-index: 1; transform: translate3d(0, 0, 0)'; + div_new.style.cssText += 'overflow: hidden; z-index: 0; transform: translate3d(0, 0, 0)'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)'; + div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, '+ height +'px, 0)'; + }, 1); + break; + + case 'slide-up': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'; + div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, '+ height +'px, 0)'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)'; + div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)'; + }, 1); + break; + + case 'flip-left': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: rotateY(0deg)'; + div_new.style.cssText += 'overflow: hidden; transform: rotateY(-180deg)'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: rotateY(0deg)'; + div_old.style.cssText += 'transition: '+ time +'s; transform: rotateY(180deg)'; + }, 1); + break; + + case 'flip-right': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: rotateY(0deg)'; + div_new.style.cssText += 'overflow: hidden; transform: rotateY(180deg)'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: rotateY(0deg)'; + div_old.style.cssText += 'transition: '+ time +'s; transform: rotateY(-180deg)'; + }, 1); + break; + + case 'flip-down': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: rotateX(0deg)'; + div_new.style.cssText += 'overflow: hidden; transform: rotateX(180deg)'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: rotateX(0deg)'; + div_old.style.cssText += 'transition: '+ time +'s; transform: rotateX(-180deg)'; + }, 1); + break; + + case 'flip-up': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: rotateX(0deg)'; + div_new.style.cssText += 'overflow: hidden; transform: rotateX(-180deg)'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: rotateX(0deg)'; + div_old.style.cssText += 'transition: '+ time +'s; transform: rotateX(180deg)'; + }, 1); + break; + + case 'pop-in': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'; + div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(.8); opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; transform: scale(1); opacity: 1;'; + div_old.style.cssText += 'transition: '+ time +'s;'; + }, 1); + break; + + case 'pop-out': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(1); opacity: 1;'; + div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; opacity: 1;'; + div_old.style.cssText += 'transition: '+ time +'s; transform: scale(1.7); opacity: 0;'; + }, 1); + break; + + default: + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'; + div_new.style.cssText += 'overflow: hidden; translate3d(0, 0, 0); opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += 'transition: '+ time +'s; opacity: 1;'; + div_old.style.cssText += 'transition: '+ time +'s'; + }, 1); + break; + } + + setTimeout(function () { + if (type === 'slide-down') { + $(div_old).css('z-index', '1019'); + $(div_new).css('z-index', '1020'); + } + if (div_new) { + $(div_new).css({ 'opacity': '1' }).css(w2utils.cssPrefix({ + 'transition': '', + 'transform' : '' + })); + } + if (div_old) { + $(div_old).css({ 'opacity': '1' }).css(w2utils.cssPrefix({ + 'transition': '', + 'transform' : '' + })); + } + if (typeof callBack === 'function') callBack(); + }, time * 1000); + } + + function lock (box, msg, spinner) { + var options = {}; + if (typeof msg === 'object') { + options = msg; + } else { + options.msg = msg; + options.spinner = spinner; + } + if (!options.msg && options.msg !== 0) options.msg = ''; + w2utils.unlock(box); + $(box).prepend( + '
'+ + '
' + ); + var $lock = $(box).find('.w2ui-lock'); + var mess = $(box).find('.w2ui-lock-msg'); + if (!options.msg) mess.css({ 'background-color': 'transparent', 'border': '0px' }); + if (options.spinner === true) options.msg = '
' + options.msg; + if (options.opacity != null) $lock.css('opacity', options.opacity); + if (typeof $lock.fadeIn == 'function') { + $lock.fadeIn(200); + mess.html(options.msg).fadeIn(200); + } else { + $lock.show(); + mess.html(options.msg).show(0); + } + } + + function unlock (box, speed) { + if (isInt(speed)) { + $(box).find('.w2ui-lock').fadeOut(speed); + setTimeout(function () { + $(box).find('.w2ui-lock').remove(); + $(box).find('.w2ui-lock-msg').remove(); + }, speed); + } else { + $(box).find('.w2ui-lock').remove(); + $(box).find('.w2ui-lock-msg').remove(); + } + } + + /** + * Used in w2popup, w2grid, w2form, w2layout + * should be called with .call(...) method + */ + + function message(where, options) { + var obj = this, closeTimer, edata; + // var where.path = 'w2popup'; + // var where.title = '.w2ui-popup-title'; + // var where.body = '.w2ui-box'; + $().w2tag(); // hide all tags + if (!options) options = { width: 200, height: 100 }; + if (options.on == null) $.extend(options, w2utils.event); + if (options.width == null) options.width = 200; + if (options.height == null) options.height = 100; + var pWidth = parseInt($(where.box).width()); + var pHeight = parseInt($(where.box).height()); + var titleHeight = parseInt($(where.box).find(where.title).css('height') || 0); + if (options.width > pWidth) options.width = pWidth - 10; + if (options.height > pHeight - titleHeight) options.height = pHeight - 10 - titleHeight; + options.originalWidth = options.width; + options.originalHeight = options.height; + if (parseInt(options.width) < 0) options.width = pWidth + options.width; + if (parseInt(options.width) < 10) options.width = 10; + if (parseInt(options.height) < 0) options.height = pHeight + options.height - titleHeight; + if (parseInt(options.height) < 10) options.height = 10; + if (options.hideOnClick == null) options.hideOnClick = false; + var poptions = $(where.box).data('options') || {}; + 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 = $(where.box).find(where.title); + + // if some messages are closing, insta close them + var $tmp = $(where.box).find('.w2ui-message.w2ui-closing'); + if ($(where.box).find('.w2ui-message.w2ui-closing').length > 0) { + clearTimeout(closeTimer); + closeCB($tmp, $tmp.data('options') || {}); + } + var msgCount = $(where.box).find('.w2ui-message').length; + // remove message + if ($.trim(options.html) === '' && $.trim(options.body) === '' && $.trim(options.buttons) === '') { + if (msgCount === 0) return; // no messages at all + var $msg = $(where.box).find('#w2ui-message'+ (msgCount-1)); + var options = $msg.data('options') || {}; + // before event + edata = options.trigger({ phase: 'before', type: 'close', target: 'self' }); + if (edata.isCancelled === true) return; + // default behavior + $msg.css(w2utils.cssPrefix({ + 'transition': '0.15s', + 'transform': 'translateY(-' + options.height + 'px)' + })).addClass('w2ui-closing'); + if (msgCount == 1) { + if (this.unlock) { + if (where.param) this.unlock(where.param, 150); else this.unlock(150); + } + } else { + $(where.box).find('#w2ui-message'+ (msgCount-2)).css('z-index', 1500); + } + closeTimer = setTimeout(function () { closeCB($msg, options) }, 150); + + } else { + + if ($.trim(options.body) !== '' || $.trim(options.buttons) !== '') { + options.html = '
'+ (options.body || '') +'
'+ + '
'+ (options.buttons || '') +'
'; + } + // hide previous messages + $(where.box).find('.w2ui-message').css('z-index', 1390); + head.data('old-z-index', head.css('z-index')); + head.css('z-index', 1501); + // add message + $(where.box).find(where.body) + .before(''); + $(where.box).find('#w2ui-message'+ msgCount) + .data('options', options) + .data('prev_focus', $(':focus')); + var display = $(where.box).find('#w2ui-message'+ msgCount).css('display'); + $(where.box).find('#w2ui-message'+ msgCount).css(w2utils.cssPrefix({ + 'transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)') + })); + if (display == 'none') { + $(where.box).find('#w2ui-message'+ msgCount).show().html(options.html); + options.box = $(where.box).find('#w2ui-message'+ msgCount); + // before event + edata = options.trigger({ phase: 'before', type: 'open', target: 'self' }); + if (edata.isCancelled === true) { + head.css('z-index', head.data('old-z-index')); + $(where.box).find('#w2ui-message'+ msgCount).remove(); + return; + } + // timer needs to animation + setTimeout(function () { + $(where.box).find('#w2ui-message'+ msgCount).css(w2utils.cssPrefix({ + 'transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)') + })); + }, 1); + // timer for lock + if (msgCount === 0 && this.lock) { + if (where.param) this.lock(where.param); else this.lock(); + } + setTimeout(function() { + // has to be on top of lock + $(where.box).find('#w2ui-message'+ msgCount).css(w2utils.cssPrefix({ 'transition': '0s' })); + // event after + options.trigger($.extend(edata, { phase: 'after' })); + }, 350); + } + } + + function closeCB($msg, options) { + if (edata == null) { + // before event + edata = options.trigger({ phase: 'before', type: 'open', target: 'self' }); + if (edata.isCancelled === true) { + head.css('z-index', head.data('old-z-index')); + $(where.box).find('#w2ui-message'+ msgCount).remove(); + return; + } + } + var $focus = $msg.data('prev_focus'); + $msg.remove(); + if ($focus && $focus.length > 0) { + $focus.focus(); + } else { + if (obj && obj.focus) obj.focus(); + } + head.css('z-index', head.data('old-z-index')); + // event after + options.trigger($.extend(edata, { phase: 'after' })); + } + } + + function getSize (el, type) { + var $el = $(el); + var bwidth = { + left : parseInt($el.css('border-left-width')) || 0, + right : parseInt($el.css('border-right-width')) || 0, + top : parseInt($el.css('border-top-width')) || 0, + bottom : parseInt($el.css('border-bottom-width')) || 0 + }; + var mwidth = { + left : parseInt($el.css('margin-left')) || 0, + right : parseInt($el.css('margin-right')) || 0, + top : parseInt($el.css('margin-top')) || 0, + bottom : parseInt($el.css('margin-bottom')) || 0 + }; + var pwidth = { + left : parseInt($el.css('padding-left')) || 0, + right : parseInt($el.css('padding-right')) || 0, + top : parseInt($el.css('padding-top')) || 0, + bottom : parseInt($el.css('padding-bottom')) || 0 + }; + switch (type) { + case 'top' : return bwidth.top + mwidth.top + pwidth.top; + case 'bottom' : return bwidth.bottom + mwidth.bottom + pwidth.bottom; + case 'left' : return bwidth.left + mwidth.left + pwidth.left; + case 'right' : return bwidth.right + mwidth.right + pwidth.right; + case 'width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right + parseInt($el.width()); + case 'height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom + parseInt($el.height()); + case '+width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right; + case '+height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom; + } + return 0; + } + + function getStrWidth (str, styles) { + var w, html = '
'+ + encodeTags(str) + + '
'; + $('body').append(html); + w = $('#_tmp_width').width(); + $('#_tmp_width').remove(); + return w; + } + + function lang (phrase) { + var translation = this.settings.phrases[phrase]; + if (translation == null) return phrase; else return translation; + } + + function locale (locale) { + if (!locale) locale = 'en-us'; + + // if the locale is an object, not a string, than we assume it's a + if(typeof locale !== "string" ) { + w2utils.settings = $.extend(true, w2utils.settings, locale); + return; + } + + if (locale.length === 5) locale = 'locale/'+ locale +'.json'; + + // clear phrases from language before + w2utils.settings.phrases = {}; + + // load from the file + $.ajax({ + url : locale, + type : "GET", + dataType : "JSON", + async : false, + success : function (data, status, xhr) { + w2utils.settings = $.extend(true, w2utils.settings, data); + }, + error : function (xhr, status, msg) { + console.log('ERROR: Cannot load locale '+ locale); + } + }); + } + + function scrollBarSize () { + if (tmp.scrollBarSize) return tmp.scrollBarSize; + var html = + '
'+ + '
1
'+ + '
'; + $('body').append(html); + tmp.scrollBarSize = 100 - $('#_scrollbar_width > div').width(); + $('#_scrollbar_width').remove(); + if (String(navigator.userAgent).indexOf('MSIE') >= 0) tmp.scrollBarSize = tmp.scrollBarSize / 2; // need this for IE9+ + return tmp.scrollBarSize; + } + + function checkName (params, component) { // was w2checkNameParam + if (!params || params.name == null) { + console.log('ERROR: The parameter "name" is required but not supplied in $().'+ component +'().'); + return false; + } + if (w2ui[params.name] != null) { + console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ params.name +').'); + return false; + } + if (!w2utils.isAlphaNumeric(params.name)) { + console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); + return false; + } + return true; + } + + function checkUniqueId (id, items, itemsDecription, objName) { // was w2checkUniqueId + if (!$.isArray(items)) items = [items]; + for (var i = 0; i < items.length; i++) { + if (items[i].id === id) { + console.log('ERROR: The parameter "id='+ id +'" is not unique within the current '+ itemsDecription +'. (obj: '+ objName +')'); + return false; + } + } + return true; + } + + function parseRoute(route) { + var keys = []; + var path = route + .replace(/\/\(/g, '(?:/') + .replace(/\+/g, '__plus__') + .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional) { + keys.push({ name: key, optional: !! optional }); + slash = slash || ''; + return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || ''); + }) + .replace(/([\/.])/g, '\\$1') + .replace(/__plus__/g, '(.+)') + .replace(/\*/g, '(.*)'); + return { + path : new RegExp('^' + path + '$', 'i'), + keys : keys + }; + } + + function cssPrefix(field, value, returnString) { + var css = {}; + var newCSS = {}; + var ret = ''; + if (!$.isPlainObject(field)) { + css[field] = value; + } else { + css = field; + if (value === true) returnString = true; + } + for (var c in css) { + newCSS[c] = css[c]; + newCSS['-webkit-'+c] = css[c]; + newCSS['-moz-'+c] = css[c].replace('-webkit-', '-moz-'); + newCSS['-ms-'+c] = css[c].replace('-webkit-', '-ms-'); + newCSS['-o-'+c] = css[c].replace('-webkit-', '-o-'); + } + if (returnString === true) { + for (var c in newCSS) { + ret += c + ': ' + newCSS[c] + '; '; + } + } else { + ret = newCSS; + } + return ret; + } + + function getCursorPosition(input) { + if (input == null) return null; + var caretOffset = 0; + var doc = input.ownerDocument || input.document; + var win = doc.defaultView || doc.parentWindow; + var sel; + if (input.tagName && input.tagName.toUpperCase() == 'INPUT' && input.selectionStart) { + // standards browser + caretOffset = input.selectionStart; + } else { + if (win.getSelection) { + sel = win.getSelection(); + if (sel.rangeCount > 0) { + var range = sel.getRangeAt(0); + var preCaretRange = range.cloneRange(); + preCaretRange.selectNodeContents(input); + preCaretRange.setEnd(range.endContainer, range.endOffset); + caretOffset = preCaretRange.toString().length; + } + } else if ( (sel = doc.selection) && sel.type != "Control") { + var textRange = sel.createRange(); + var preCaretTextRange = doc.body.createTextRange(); + preCaretTextRange.moveToElementText(input); + preCaretTextRange.setEndPoint("EndToEnd", textRange); + caretOffset = preCaretTextRange.text.length; + } + } + return caretOffset; + } + + function setCursorPosition(input, pos, posEnd) { + var range = document.createRange(); + var el, sel = window.getSelection(); + if (input == null) return; + for (var i = 0; i < input.childNodes.length; i++) { + var tmp = $(input.childNodes[i]).text(); + if (input.childNodes[i].tagName) { + tmp = $(input.childNodes[i]).html(); + tmp = tmp.replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/ /g, ' '); + } + if (pos <= tmp.length) { + el = input.childNodes[i]; + if (el.childNodes && el.childNodes.length > 0) el = el.childNodes[0]; + if (el.childNodes && el.childNodes.length > 0) el = el.childNodes[0]; + break; + } else { + pos -= tmp.length; + } + } + if (el == null) return; + if (pos > el.length) pos = el.length; + range.setStart(el, pos); + if (posEnd) { + range.setEnd(el, posEnd); + } else { + range.collapse(true); + } + sel.removeAllRanges(); + sel.addRange(range); + } + + function testLocalStorage() { + // test if localStorage is available, see issue #1282 + // original code: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js + var str = 'w2ui_test'; + try { + localStorage.setItem(str, str); + localStorage.removeItem(str); + return true; + } catch (e) { + return false; + } + } + +})(jQuery); + +/*********************************************************** +* Formatters object +* --- Primariy used in grid +* +*********************************************************/ + +w2utils.formatters = { + + 'number': function (value, params) { + if (parseInt(params) > 20) params = 20; + if (parseInt(params) < 0) params = 0; + if (value == null || value === '') return ''; + return w2utils.formatNumber(parseFloat(value), params, true); + }, + + 'float': function (value, params) { + return w2utils.formatters['number'](value, params); + }, + + 'int': function (value, params) { + return w2utils.formatters['number'](value, 0); + }, + + 'money': function (value, params) { + if (value == null || value === '') return ''; + var data = w2utils.formatNumber(Number(value), w2utils.settings.currencyPrecision || 2); + return (w2utils.settings.currencyPrefix || '') + data + (w2utils.settings.currencySuffix || ''); + }, + + 'currency': function (value, params) { + return w2utils.formatters['money'](value, params); + }, + + 'percent': function (value, params) { + if (value == null || value === '') return ''; + return w2utils.formatNumber(value, params || 1) + '%'; + }, + + 'size': function (value, params) { + if (value == null || value === '') return ''; + return w2utils.formatSize(parseInt(value)); + }, + + 'date': function (value, params) { + if (params === '') params = w2utils.settings.dateFormat; + if (value == null || value === 0 || value === '') return ''; + var dt = w2utils.isDateTime(value, params, true); + if (dt === false) dt = w2utils.isDate(value, params, true); + return '' + w2utils.formatDate(dt, params) + ''; + }, + + 'datetime': function (value, params) { + if (params === '') params = w2utils.settings.datetimeFormat; + if (value == null || value === 0 || value === '') return ''; + var dt = w2utils.isDateTime(value, params, true); + if (dt === false) dt = w2utils.isDate(value, params, true); + return '' + w2utils.formatDateTime(dt, params) + ''; + }, + + 'time': function (value, params) { + if (params === '') params = w2utils.settings.timeFormat; + if (params === 'h12') params = 'hh:mi pm'; + if (params === 'h24') params = 'h24:mi'; + if (value == null || value === 0 || value === '') return ''; + var dt = w2utils.isDateTime(value, params, true); + if (dt === false) dt = w2utils.isDate(value, params, true); + return '' + w2utils.formatTime(value, params) + ''; + }, + + 'timestamp': function (value, params) { + if (params === '') params = w2utils.settings.datetimeFormat; + if (value == null || value === 0 || value === '') return ''; + var dt = w2utils.isDateTime(value, params, true); + if (dt === false) dt = w2utils.isDate(value, params, true); + return dt.toString ? dt.toString() : ''; + }, + + 'gmt': function (value, params) { + if (params === '') params = w2utils.settings.datetimeFormat; + if (value == null || value === 0 || value === '') return ''; + var dt = w2utils.isDateTime(value, params, true); + if (dt === false) dt = w2utils.isDate(value, params, true); + return dt.toUTCString ? dt.toUTCString() : ''; + }, + + 'age': function (value, params) { + if (value == null || value === 0 || value === '') return ''; + var dt = w2utils.isDateTime(value, null, true); + if (dt === false) dt = w2utils.isDate(value, null, true); + return '' + w2utils.age(value) + (params ? (' ' + params) : '') + ''; + }, + + 'interval': function (value, params) { + if (value == null || value === 0 || value === '') return ''; + return w2utils.interval(value) + (params ? (' ' + params) : ''); + }, + + 'toggle': function (value, params) { + return (value ? 'Yes' : ''); + }, + + 'password': function (value, params) { + var ret = ""; + for (var i=0; i < value.length; i++) { + ret += "*"; + } + return ret; + } +}; + +/*********************************************************** +* Generic Event Object +* --- This object is reused across all other +* --- widgets in w2ui. +* +*********************************************************/ + +w2utils.event = { + + on: function (edata, handler) { + var $ = jQuery; + var scope; + // allow 'eventName.scope' syntax + if (typeof edata == 'string' && edata.indexOf('.') != -1) { + var tmp = edata.split('.'); + edata = tmp[0]; + scope = tmp[1]; + } + // allow 'eventName:after' syntax + if (typeof edata == 'string' && edata.indexOf(':') != -1) { + var tmp = edata.split(':'); + if (['complete', 'done'].indexOf(edata[1]) != -1) edata[1] = 'after'; + edata = { + type : tmp[0], + execute : tmp[1] + }; + } + if (!$.isPlainObject(edata)) edata = { type: edata, scope: scope }; + edata = $.extend({ type: null, execute: 'before', target: null, onComplete: null }, edata); + // errors + if (!edata.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return; } + if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return; } + if (!$.isArray(this.handlers)) this.handlers = []; + console.log('add', edata); + this.handlers.push({ edata: edata, handler: handler }); + }, + + off: function (edata, handler) { + var $ = jQuery; + var scope; + // allow 'eventName.scope' syntax + if (typeof edata == 'string' && edata.indexOf('.') != -1) { + var tmp = edata.split('.'); + edata = tmp[0]; + scope = tmp[1]; + } + // allow 'eventName:after' syntax + if (typeof edata == 'string' && edata.indexOf(':') != -1) { + var tmp = edata.split(':'); + if (['complete', 'done'].indexOf(edata[1]) != -1) edata[1] = 'after'; + edata = { + type : tmp[0], + execute : tmp[1] + } + } + if (!$.isPlainObject(edata)) edata = { type: edata }; + edata = $.extend({}, { type: null, execute: 'before', target: null, onComplete: null }, edata); + // errors + if (!edata.type && !scope) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return; } + if (!handler) { handler = null; } + // remove handlers + var newHandlers = []; + for (var h = 0, len = this.handlers.length; h < len; h++) { + var t = this.handlers[h]; + if ((t.edata.type === edata.type || edata.type === '*' || (t.edata.scope != null && edata.type == '')) && + (t.edata.target === edata.target || edata.target == null) && + (t.edata.execute === edata.execute || edata.execute == null) && + (t.handler === handler || handler == null || (scope != null && t.edata.scope == scope))) + { + // match + } else { + newHandlers.push(t); + } + } + this.handlers = newHandlers; + }, + + trigger: function (edata) { + var $ = jQuery; + var edata = $.extend({ type: null, phase: 'before', target: null, doneHandlers: [] }, edata, { + isStopped : false, + isCancelled : false, + done : function (handler) { this.doneHandlers.push(handler); }, + preventDefault : function () { this.isCancelled = true; }, + stopPropagation : function () { this.isStopped = true; } + }); + if (edata.phase === 'before') edata.onComplete = null; + var args, fun, tmp; + if (edata.target == null) edata.target = null; + if (!$.isArray(this.handlers)) this.handlers = []; + // process events in REVERSE order + for (var h = this.handlers.length-1; h >= 0; h--) { + var item = this.handlers[h]; + if ((item.edata.type === edata.type || item.edata.type === '*') && + (item.edata.target === edata.target || item.edata.target == null) && + (item.edata.execute === edata.phase || item.edata.execute === '*' || item.edata.phase === '*')) + { + edata = $.extend({}, item.edata, edata); + // check handler arguments + args = []; + tmp = new RegExp(/\((.*?)\)/).exec(item.handler); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + item.handler.call(this, edata.target, edata); // old way for back compatibility + } else { + item.handler.call(this, edata); // new way + } + if (edata.isStopped === true || edata.stop === true) return edata; // back compatibility edata.stop === true + } + } + // main object events + var funName = 'on' + edata.type.substr(0,1).toUpperCase() + edata.type.substr(1); + if (edata.phase === 'before' && typeof this[funName] === 'function') { + fun = this[funName]; + // check handler arguments + args = []; + tmp = new RegExp(/\((.*?)\)/).exec(fun); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + fun.call(this, edata.target, edata); // old way for back compatibility + } else { + fun.call(this, edata); // new way + } + if (edata.isStopped === true || edata.stop === true) return edata; // back compatibility edata.stop === true + } + // item object events + if (edata.object != null && edata.phase === 'before' && + typeof edata.object[funName] === 'function') + { + fun = edata.object[funName]; + // check handler arguments + args = []; + tmp = new RegExp(/\((.*?)\)/).exec(fun); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + fun.call(this, edata.target, edata); // old way for back compatibility + } else { + fun.call(this, edata); // new way + } + if (edata.isStopped === true || edata.stop === true) return edata; + } + // execute onComplete + if (edata.phase === 'after') { + if (typeof edata.onComplete === 'function') edata.onComplete.call(this, edata); + for (var i = 0; i < edata.doneHandlers.length; i++) { + if (typeof edata.doneHandlers[i] == 'function') { + edata.doneHandlers[i].call(this, edata); + } + } + } + return edata; + } +}; + +/*********************************************************** +* Commonly used plugins +* --- used primarily in grid and form +* +*********************************************************/ + +(function ($) { + + $.fn.w2render = function (name) { + if ($(this).length > 0) { + if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]); + if (typeof name === 'object') name.render($(this)[0]); + } + }; + + $.fn.w2destroy = function (name) { + if (!name && this.length > 0) name = this.attr('name'); + if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy(); + if (typeof name === 'object') name.destroy(); + }; + + $.fn.w2marker = function () { + var str = Array.prototype.slice.call(arguments, 0); + if (Array.isArray(str[0])) str = str[0]; + if (str.length === 0 || !str[0]) { // remove marker + return $(this).each(clearMarkedText); + } else { // add marker + return $(this).each(function (index, el) { + clearMarkedText(index, el); + for (var s = 0; s < str.length; s++) { + var tmp = str[s]; + if (typeof tmp !== 'string') tmp = String(tmp); + // escape regex special chars + tmp = tmp.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&").replace(/&/g, '&').replace(//g, '<'); + var regex = new RegExp(tmp + '(?!([^<]+)?>)', "gi"); // only outside tags + el.innerHTML = el.innerHTML.replace(regex, replaceValue); + } + function replaceValue(matched) { // mark new + return '' + matched + ''; + } + }); + } + + function clearMarkedText(index, el) { + while (el.innerHTML.indexOf('') != -1) { + el.innerHTML = el.innerHTML.replace(/\((.|\n|\r)*)\<\/span\>/ig, '$1'); // unmark + } + } + }; + + // -- w2tag - there can be multiple on screen at a time + + $.fn.w2tag = function (text, options) { + // only one argument + if (arguments.length == 1 && typeof text == 'object') { + options = text; + if (options.html != null) text = options.html; + } + // default options + options = $.extend({ + id : null, // id for the tag, otherwise input id is used + html : text, // or html + position : 'right|top', // can be left, right, top, bottom + align : 'none', // can be none, left, right (only works for potision: top | bottom) + left : 0, // delta for left coordinate + top : 0, // delta for top coordinate + style : '', // adition style for the tag + css : {}, // add css for input when tag is shown + className : '', // add class bubble + inputClass : '', // add class for input when tag is shown + onShow : null, // callBack when shown + onHide : null, // callBack when hidden + hideOnKeyPress : true, // hide tag if key pressed + hideOnBlur : false, // hide tag on blur + hideOnClick : false // hide tag on document click + }, options); + if (options.name != null && options.id == null) options.id = options.name; + + // for backward compatibility + if (options['class'] !== '' && options.inputClass === '') options.inputClass = options['class']; + + // remove all tags + if ($(this).length === 0) { + $('.w2ui-tag').each(function (index, el) { + var opt = $(el).data('options'); + if (opt == null) opt = {}; + $($(el).data('taged-el')) + .removeClass(opt.inputClass) + .removeData('w2tag') + .removeData('checkIfMoved'); + clearInterval($(el).data('timer')); + $(el).remove(); + }); + return; + } + return $(this).each(function (index, el) { + // show or hide tag + var origID = (options.id ? options.id : el.id); + var tagID = w2utils.escapeId(origID); + var $tags = $('#w2ui-tag-'+tagID); + if (text === '' || text == null) { + // remmove element + $tags.css('opacity', 0); + clearInterval($tags.data('timer')); + $tags.remove(); + return; + } else if ($tags.length !== 0) { + // if already present + options = $.extend($tags.data('options'), options); + $tags.data('options', options); + $tags.find('.w2ui-tag-body') + .attr('style', options.style) + .addClass(options.className) + .html(options.html); + checkIfMoved(true); + } else { + var originalCSS = ''; + if ($(el).length > 0) originalCSS = $(el)[0].style.cssText; + // insert + $('body').append( + ''); + $tags = $('#w2ui-tag-'+tagID); + $(el).data('w2tag', $tags.get(0)).data('checkIfMoved', checkIfMoved); + } + + // need time out to allow tag to be rendered + setTimeout(function () { + $tags.css('display', 'block'); + if (!$(el).offset()) return; + var pos = checkIfMoved(true); + if (pos == null) return; + $tags.css({ + opacity : '1', + left : pos.left + 'px', + top : pos.top + 'px' + }) + .data('options', options) + .data('taged-el', el) + .data('position', pos.left + 'x' + pos.top) + .data('timer', setTimeout(checkIfMoved, 100)) + .find('.w2ui-tag-body').addClass(pos['posClass']); + + $(el).css(options.css) + .off('.w2tag') + .addClass(options.inputClass); + + if (options.hideOnKeyPress) { + $(el).on('keypress.w2tag', hideTag); + } + if (options.hideOnBlur) { + $(el).on('blur.w2tag', hideTag); + } + if (options.hideOnClick) { + $(document).on('click.w2tag', hideTag) + } + if (typeof options.onShow === 'function') options.onShow(); + }, 1); + + // bind event to hide it + function hideTag() { + $tags = $('#w2ui-tag-'+tagID); + if ($tags.length <= 0) return; + clearInterval($tags.data('timer')); + $tags.remove(); + $(document).off('.w2tag'); + $(el).off('.w2tag', hideTag) + .removeClass(options.inputClass) + .removeData('w2tag') + .removeData('checkIfMoved'); + if ($(el).length > 0) $(el)[0].style.cssText = originalCSS; + if (typeof options.onHide === 'function') options.onHide(); + } + + function checkIfMoved(checkOnly, instant) { + // monitor if destroyed + var offset = $(el).offset(); + if ($(el).length === 0 || (offset.left === 0 && offset.top === 0) || $tags.find('.w2ui-tag-body').length === 0) { + clearInterval($tags.data('timer')); + hideTag(); + return; + } + if (!instant) setTimeout(checkIfMoved, 100); + // monitor if moved + var posClass = 'w2ui-tag-right'; + var posLeft = parseInt(offset.left + el.offsetWidth + (options.left ? options.left : 0)); + var posTop = parseInt(offset.top + (options.top ? options.top : 0)); + var tagBody = $tags.find('.w2ui-tag-body'); + var width = tagBody[0].offsetWidth; + var height = tagBody[0].offsetHeight; + if (typeof options.position == 'string' && options.position.indexOf('|') != -1) { + options.position = options.position.split('|'); + } + if (options.position == 'top') { + posClass = 'w2ui-tag-top'; + posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - 14; + posTop = parseInt(offset.top + (options.top ? options.top : 0)) - height - 10; + } + else if (options.position == 'bottom') { + posClass = 'w2ui-tag-bottom'; + posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - 14; + posTop = parseInt(offset.top + el.offsetHeight + (options.top ? options.top : 0)) + 10; + } + else if (options.position == 'left') { + posClass = 'w2ui-tag-left'; + posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - width - 20; + posTop = parseInt(offset.top + (options.top ? options.top : 0)); + } + else if (Array.isArray(options.position)) { + // try to fit the tag on screen in the order defined in the array + var maxWidth = window.innerWidth; + var maxHeight = window.innerHeight + for (var i=0; i= 0) break; + } + else if (pos == 'top') { + posClass = 'w2ui-tag-top'; + posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - 14; + posTop = parseInt(offset.top + (options.top ? options.top : 0)) - height - 10; + if(posLeft+width <= maxWidth && posTop >= 0) break; + } + else if (pos == 'bottom') { + posClass = 'w2ui-tag-bottom'; + posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - 14; + posTop = parseInt(offset.top + el.offsetHeight + (options.top ? options.top : 0)) + 10; + if (posLeft+width <= maxWidth && posTop+height <= maxHeight) break; + } + } + if (tagBody.data('posClass') !== posClass) { + tagBody.removeClass('w2ui-tag-right w2ui-tag-left w2ui-tag-top w2ui-tag-bottom') + .addClass(posClass) + .data('posClass', posClass); + } + } + if ($tags.data('position') !== posLeft + 'x' + posTop && checkOnly !== true) { + $tags.css(w2utils.cssPrefix({ 'transition': (instant ? '0s' : '.2s') })).css({ + left: posLeft + 'px', + top : posTop + 'px' + }).data('position', posLeft + 'x' + posTop); + } + return { left: posLeft, top: posTop, posClass: posClass }; + } + }); + }; + + // w2overlay - appears under the element, there can be only one at a time + + $.fn.w2overlay = function (html, options) { + var obj = this; + var name = ''; + var defaults = { + name : null, // it not null, then allows multiple concurrent overlays + html : '', // html text to display + align : 'none', // can be none, left, right, both + left : 0, // offset left + top : 0, // offset top + tipLeft : 30, // tip offset left + noTip : false, // if true - no tip will be displayed + selectable : false, + width : 0, // fixed width + height : 0, // fixed height + maxWidth : null, // max width if any + maxHeight : null, // max height if any + contextMenu : false, // if true, it will be opened at mouse position + pageX : null, + pageY : null, + originalEvent : null, + style : '', // additional style for main div + 'class' : '', // additional class name for main div + overlayStyle: '', + onShow : null, // event on show + onHide : null, // event on hide + openAbove : false, // show above control + tmp : {} + }; + if (arguments.length == 1) { + if (typeof html == 'object') { + options = html; + } else { + options = { html: html }; + } + } + if (arguments.length == 2) options.html = html; + if (!$.isPlainObject(options)) options = {}; + options = $.extend({}, defaults, options); + if (options.name) name = '-' + options.name; + // hide + var tmp_hide; + if (this.length === 0 || options.html === '' || options.html == null) { + if ($('#w2ui-overlay'+ name).length > 0) { + tmp_hide = $('#w2ui-overlay'+ name)[0].hide; + if (typeof tmp_hide === 'function') tmp_hide(); + } else { + $('#w2ui-overlay'+ name).remove(); + } + return $(this); + } + // hide previous if any + if ($('#w2ui-overlay'+ name).length > 0) { + tmp_hide = $('#w2ui-overlay'+ name)[0].hide; + $(document).off('.w2overlayHide'); + if (typeof tmp_hide === 'function') tmp_hide(); + } + if (obj.length > 0 && (obj[0].tagName == null || obj[0].tagName.toUpperCase() == 'BODY')) options.contextMenu = true; + if (options.contextMenu && options.originalEvent) { + options.pageX = options.originalEvent.pageX; + options.pageY = options.originalEvent.pageY; + } + if (options.contextMenu && (options.pageX == null || options.pageY == null)) { + console.log('ERROR: to display menu at mouse location, pass options.pageX and options.pageY.'); + } + // append + $('body').append( + '' + ); + // init + var div1 = $('#w2ui-overlay'+ name); + var div2 = div1.find(' > div'); + div2.html(options.html); + // pick bg color of first div + var bc = div2.css('background-color'); + if (bc != null && bc !== 'rgba(0, 0, 0, 0)' && bc !== 'transparent') div1.css({ 'background-color': bc, 'border-color': bc }); + + var offset = $(obj).offset() || {}; + div1.data('element', obj.length > 0 ? obj[0] : null) + .data('options', options) + .data('position', offset.left + 'x' + offset.top) + .fadeIn('fast') + .on('click', function (event) { + // if there is label for input, it will produce 2 click events + if (event.target.tagName.toUpperCase() == 'LABEL') event.stopPropagation(); + }) + .on('mousedown', function (event) { + $('#w2ui-overlay'+ name).data('keepOpen', true); + if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName.toUpperCase()) == -1 && !options.selectable) { + event.preventDefault(); + } + }); + div1[0].hide = hide; + div1[0].resize = resize; + + // need time to display + setTimeout(function () { + resize(); + $(document).off('.w2overlayHide').on('click.w2overlayHide', hide); + if (typeof options.onShow === 'function') options.onShow(); + }, 10); + + monitor(); + return $(this); + + // monitor position + function monitor() { + var tmp = $('#w2ui-overlay'+ name); + if (tmp.data('element') !== obj[0]) return; // it if it different overlay + if (tmp.length === 0) return; + var offset = $(obj).offset() || {}; + var pos = offset.left + 'x' + offset.top; + if (tmp.data('position') !== pos) { + hide(); + } else { + setTimeout(monitor, 250); + } + } + + // click anywhere else hides the drop down + function hide(event) { + if (event && event.button !== 0) return; // only for left click button + var div1 = $('#w2ui-overlay'+ name); + if (div1.data('keepOpen') === true) { + div1.removeData('keepOpen'); + return; + } + var result; + if (typeof options.onHide === 'function') result = options.onHide(); + if (result === false) return; + div1.remove(); + $(document).off('click', hide); + clearInterval(div1.data('timer')); + } + + function resize () { + var div1 = $('#w2ui-overlay'+ name); + var div2 = div1.find(' > div'); + var menu = $('#w2ui-overlay'+ name +' div.menu'); + menu.css('overflow-y', 'hidden'); + // if goes over the screen, limit height and width + if (div1.length > 0) { + div2.height('auto').width('auto'); + // width/height + var overflowX = false; + var overflowY = false; + var h = div2.height(); + var w = div2.width(); + if (options.width && options.width < w) w = options.width; + if (w < 30) w = 30; + // if content of specific height + if (options.tmp.contentHeight) { + h = parseInt(options.tmp.contentHeight); + div2.height(h); + setTimeout(function () { + var $div = div2.find('div.menu'); + if (h > $div.height()) { + div2.find('div.menu').css('overflow-y', 'hidden'); + } + }, 1); + setTimeout(function () { + var $div = div2.find('div.menu'); + if ($div.css('overflow-y') != 'auto') $div.css('overflow-y', 'auto'); + }, 10); + } + if (options.tmp.contentWidth && options.align != 'both') { + w = parseInt(options.tmp.contentWidth); + div2.width(w); + setTimeout(function () { + if (w > div2.find('div.menu > table').width()) { + div2.find('div.menu > table').css('overflow-x', 'hidden'); + } + }, 1); + setTimeout(function () { + div2.find('div.menu > table').css('overflow-x', 'auto'); + }, 10); + } + // adjust position + var boxLeft = options.left; + var boxWidth = options.width; + var tipLeft = options.tipLeft; + // alignment + switch (options.align) { + case 'both': + boxLeft = 17; + if (options.width === 0) options.width = w2utils.getSize($(obj), 'width'); + if (options.maxWidth && options.width > options.maxWidth) options.width = options.maxWidth; + break; + case 'left': + boxLeft = 17; + break; + case 'right': + boxLeft = w2utils.getSize($(obj), 'width') - w + 10; + tipLeft = w - 40; + break; + } + if (w === 30 && !boxWidth) boxWidth = 30; else boxWidth = (options.width ? options.width : 'auto'); + var tmp = (w - 17) / 2; + if (boxWidth != 'auto') tmp = (boxWidth - 17) / 2; + if (tmp < 25) { + boxLeft = 25 - tmp; + tipLeft = Math.floor(tmp); + } + // Y coord + var X, Y, offsetTop; + if (options.contextMenu) { // context menu + X = options.pageX + 8; + Y = options.pageY - 0; + offsetTop = options.pageY; + } else { + var offset = obj.offset() || {}; + X = ((offset.left > 25 ? offset.left : 25) + boxLeft); + Y = (offset.top + w2utils.getSize(obj, 'height') + options.top + 7); + offsetTop = offset.top; + } + div1.css({ + left : X + 'px', + top : Y + 'px', + 'min-width' : boxWidth, + 'min-height': (options.height ? options.height : 'auto') + }); + // $(window).height() - has a problem in FF20 + var offset = div2.offset() || {}; + var maxHeight = window.innerHeight + $(document).scrollTop() - offset.top - 7; + var maxWidth = window.innerWidth + $(document).scrollLeft() - offset.left - 7; + if (options.contextMenu) { // context menu + maxHeight = window.innerHeight + $(document).scrollTop() - options.pageY - 15; + maxWidth = window.innerWidth + $(document).scrollLeft() - options.pageX; + } + + if ((maxHeight > -50 && maxHeight < 210) || options.openAbove === true) { + var tipOffset; + // show on top + if (options.contextMenu) { // context menu + maxHeight = options.pageY - 7; + tipOffset = 5; + } else { + maxHeight = offset.top - $(document).scrollTop() - 7; + tipOffset = 24; + } + if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; + if (h > maxHeight) { + overflowY = true; + div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); + h = maxHeight; + } + div1.addClass('bottom-arrow'); + div1.css('top', (offsetTop - h - tipOffset + options.top) + 'px'); + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { margin-left: '+ parseInt(tipLeft) +'px; }'+ + '#w2ui-overlay'+ name +':after { margin-left: '+ parseInt(tipLeft) +'px; }' + ); + } else { + // show under + if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; + if (h > maxHeight) { + overflowY = true; + div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); + } + div1.addClass('top-arrow'); + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { margin-left: '+ parseInt(tipLeft) +'px; }'+ + '#w2ui-overlay'+ name +':after { margin-left: '+ parseInt(tipLeft) +'px; }' + ); + } + // check width + w = div2.width(); + maxWidth = window.innerWidth + $(document).scrollLeft() - offset.left - 7; + if (options.maxWidth && maxWidth > options.maxWidth) maxWidth = options.maxWidth; + if (w > maxWidth && options.align !== 'both') { + options.align = 'right'; + setTimeout(function () { resize(); }, 1); + } + // don't show tip + if (options.contextMenu || options.noTip) { // context menu + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { display: none; }'+ + '#w2ui-overlay'+ name +':after { display: none; }' + ); + } + // check scroll bar (needed to avoid horizontal scrollbar) + if (overflowY && options.align != 'both') div2.width(w + w2utils.scrollBarSize() + 2); + } + menu.css('overflow-y', 'auto'); + } + }; + + $.fn.w2menu = function (menu, options) { + /* + ITEM STRUCTURE + item : { + id : null, + text : '', + style : '', + img : '', + icon : '', + count : '', + tooltip : '', + hidden : false, + checked : null, + disabled : false + ... + } + */ + // if items is a function + if (options && typeof options.items == 'function') { + options.items = options.items(); + } + var defaults = { + type : 'normal', // can be normal, radio, check + index : null, // current selected + items : [], + render : null, + msgNoItems : 'No items', + onSelect : null, + tmp : {} + }; + var obj = this; + var name = ''; + if (menu === 'refresh') { + // if not show - call blur + if ($('#w2ui-overlay'+ name).length > 0) { + options = $.extend($.fn.w2menuOptions, options); + var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); + $('#w2ui-overlay'+ name +' div.menu').html(getMenuHTML()); + $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); + mresize(); + } else { + $(this).w2menu(options); + } + } else if (menu === 'refresh-index') { + var $menu = $('#w2ui-overlay'+ name +' div.menu'); + var cur = $menu.find('tr[index='+ options.index +']'); + var scrTop = $menu.scrollTop(); + $menu.find('tr.w2ui-selected').removeClass('w2ui-selected'); // clear all + cur.addClass('w2ui-selected'); // select current + // scroll into view + if (cur.length > 0) { + var top = cur[0].offsetTop - 5; // 5 is margin top + var height = $menu.height(); + $menu.scrollTop(scrTop); + if (top < scrTop || top + cur.height() > scrTop + height) { + $menu.animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear'); + } + } + mresize(); + } else { + if (arguments.length === 1) options = menu; else options.items = menu; + if (typeof options !== 'object') options = {}; + options = $.extend({}, defaults, options); + $.fn.w2menuOptions = options; + if (options.name) name = '-' + options.name; + if (typeof options.select === 'function' && typeof options.onSelect !== 'function') options.onSelect = options.select; + if (typeof options.onRender === 'function' && typeof options.render !== 'function') options.render = options.onRender; + // since only one overlay can exist at a time + $.fn.w2menuClick = function (event, index) { + var keepOpen = false; + if (['radio', 'check'].indexOf(options.type) != -1) { + if (event.shiftKey || event.metaKey || event.ctrlKey) keepOpen = true; + } + if (typeof options.onSelect === 'function') { + // need time so that menu first hides + setTimeout(function () { + options.onSelect({ + index: index, + item: options.items[index], + keepOpen: keepOpen, + originalEvent: event + }); + }, 10); + } + // do not uncomment (or enum search type is not working in grid) + // setTimeout(function () { $(document).click(); }, 50); + // -- hide + var div = $('#w2ui-overlay'+ name); + div.removeData('keepOpen'); + if (typeof div[0].hide === 'function' && !keepOpen) { + div[0].hide(); + } + }; + $.fn.w2menuDown = function (event, index) { + var $el = $(event.target).parents('tr'); + var tmp = $el.find('.w2ui-icon'); + if ((options.type == 'check') || (options.type == 'radio')) { + var item = options.items[index]; + item.checked = !item.checked; + if (item.checked) { + if (options.type == 'radio') { + tmp.parents('table').find('.w2ui-icon') + .removeClass('w2ui-icon-check') + .addClass('w2ui-icon-empty'); + } + tmp.removeClass('w2ui-icon-empty').addClass('w2ui-icon-check'); + } else if (options.type == 'check') { + tmp.removeClass('w2ui-icon-check').addClass('w2ui-icon-empty'); + } + } + // highlight record + $el.parent().find('tr').removeClass('w2ui-selected'); + $el.addClass('w2ui-selected'); + }; + var html = ''; + if (options.search) { + html += + '
'+ + ' '+ + ' '+ + '
'; + options.style += ';background-color: #ECECEC'; + options.index = 0; + for (var i = 0; i < options.items.length; i++) options.items[i].hidden = false; + } + html += ''; + var ret = $(this).w2overlay(html, options); + setTimeout(function () { + $('#w2ui-overlay'+ name +' #menu-search') + .on('keyup', change) + .on('keydown', function (event) { + // cancel tab key + if (event.keyCode === 9) { event.stopPropagation(); event.preventDefault(); } + }); + if (options.search) { + if (['text', 'password'].indexOf($(obj)[0].type) != -1 || $(obj)[0].tagName.toUpperCase() == 'TEXTAREA') return; + $('#w2ui-overlay'+ name +' #menu-search').focus(); + } + mresize(); + }, 200); + mresize(); + return ret; + } + return; + + function mresize() { + setTimeout(function () { + // show selected + $('#w2ui-overlay'+ name +' tr.w2ui-selected').removeClass('w2ui-selected'); + var cur = $('#w2ui-overlay'+ name +' tr[index='+ options.index +']'); + var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); + cur.addClass('w2ui-selected'); + if (options.tmp) options.tmp.contentHeight = $('#w2ui-overlay'+ name +' table').height() + (options.search ? 50 : 10); + if (options.tmp) options.tmp.contentWidth = $('#w2ui-overlay'+ name +' table').width(); + if ($('#w2ui-overlay'+ name).length > 0) $('#w2ui-overlay'+ name)[0].resize(); + // scroll into view + if (cur.length > 0) { + var top = cur[0].offsetTop - 5; // 5 is margin top + var el = $('#w2ui-overlay'+ name +' div.menu'); + var height = el.height(); + $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); + if (top < scrTop || top + cur.height() > scrTop + height) { + $('#w2ui-overlay'+ name +' div.menu').animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear'); + } + } + }, 1); + } + + function change(event) { + var search = this.value; + var key = event.keyCode; + var cancel = false; + switch (key) { + case 13: // enter + $('#w2ui-overlay'+ name).remove(); + $.fn.w2menuClick(event, options.index); + break; + case 9: // tab + case 27: // escape + $('#w2ui-overlay'+ name).remove(); + $.fn.w2menuClick(event, -1); + break; + case 38: // up + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index--; + while (options.index > 0 && options.items[options.index].hidden) options.index--; + if (options.index === 0 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } + if (options.index < 0) options.index = 0; + cancel = true; + break; + case 40: // down + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index++; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (options.index === options.items.length-1 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index--; + } + if (options.index >= options.items.length) options.index = options.items.length - 1; + cancel = true; + break; + } + // filter + if (!cancel) { + var shown = 0; + for (var i = 0; i < options.items.length; i++) { + var item = options.items[i]; + var prefix = ''; + var suffix = ''; + if (['is', 'begins with'].indexOf(options.match) !== -1) prefix = '^'; + if (['is', 'ends with'].indexOf(options.match) !== -1) suffix = '$'; + try { + var re = new RegExp(prefix + search + suffix, 'i'); + if (re.test(item.text) || item.text === '...') item.hidden = false; else item.hidden = true; + } catch (e) {} + // do not show selected items + if (obj.type === 'enum' && $.inArray(item.id, ids) !== -1) item.hidden = true; + if (item.hidden !== true) shown++; + } + options.index = 0; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (shown <= 0) options.index = -1; + } + $(obj).w2menu('refresh', options); + mresize(); + } + + function getMenuHTML() { + if (options.spinner) { + return '
'+ + '
'+ + '
'+ w2utils.lang('Loading...') +'
'+ + '
'; + } + var count = 0; + var menu_html = ''; + var img = null, icon = null; + for (var f = 0; f < options.items.length; f++) { + var mitem = options.items[f]; + if (typeof mitem === 'string') { + mitem = { id: mitem, text: mitem }; + } else { + if (mitem.text != null && mitem.id == null) mitem.id = mitem.text; + if (mitem.text == null && mitem.id != null) mitem.text = mitem.id; + if (mitem.caption != null) mitem.text = mitem.caption; + img = mitem.img; + icon = mitem.icon; + if (img == null) img = null; // img might be undefined + if (icon == null) icon = null; // icon might be undefined + } + if (['radio', 'check'].indexOf(options.type) != -1) { + if (mitem.checked === true) icon = 'w2ui-icon-check'; else icon = 'w2ui-icon-empty'; + } + if (mitem.hidden !== true) { + var imgd = ''; + var txt = mitem.text; + if (typeof options.render === 'function') txt = options.render(mitem, options); + if (img) imgd = ''; + if (icon) imgd = ''; + // render only if non-empty + if (txt != null && txt !== '' && !(/^-+$/.test(txt))) { + var bg = (count % 2 === 0 ? 'w2ui-item-even' : 'w2ui-item-odd'); + if (options.altRows !== true) bg = ''; + var colspan = 1; + if (imgd === '') colspan++; + if (mitem.count == null && mitem.hotkey == null) colspan++; + if (mitem.tooltip == null && mitem.hint != null) mitem.tooltip = mitem.hint; // for backward compatibility + menu_html += + ''+ + imgd + + ' '+ + ' ' + + ''; + count++; + } else { + // horizontal line + menu_html += ''; + } + } + options.items[f] = mitem; + } + if (count === 0) { + menu_html += ''; + } + menu_html += "
'+ options.msgNoItems +'
"; + return menu_html; + } + }; + + $.fn.w2color = function (options, callBack) { + var obj = this; + var el = $(this)[0]; + var index = [-1, -1]; + if ($.fn.w2colorPalette == null) { + $.fn.w2colorPalette = [ + ['000000', '555555', '888888', 'BBBBBB', 'DDDDDD', 'EEEEEE', 'F7F7F7', 'FFFFFF'], + ['FF011B', 'FF9838', 'FFFD59', '01FD55', '00FFFE', '006CE7', '9B24F4', 'FF21F5'], + ['FFEAEA', 'FCEFE1', 'FCF5E1', 'EBF7E7', 'E9F3F5', 'ECF4FC', 'EAE6F4', 'F5E7ED'], + ['F4CCCC', 'FCE5CD', 'FFF2CC', 'D9EAD3', 'D0E0E3', 'CFE2F3', 'D9D1E9', 'EAD1DC'], + ['EA9899', 'F9CB9C', 'FEE599', 'B6D7A8', 'A2C4C9', '9FC5E8', 'B4A7D6', 'D5A6BD'], + ['E06666', 'F6B26B', 'FED966', '93C47D', '76A5AF', '6FA8DC', '8E7CC3', 'C27BA0'], + ['CC0814', 'E69138', 'F1C232', '6AA84F', '45818E', '3D85C6', '674EA7', 'A54D79'], + ['99050C', 'B45F17', 'BF901F', '37761D', '124F5C', '0A5394', '351C75', '741B47'], + // ['660205', '783F0B', '7F6011', '274E12', '0C343D', '063762', '20124D', '4C1030'], + ['F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2'] // custom colors (up to 4) + ]; + } + var pal = $.fn.w2colorPalette; + if (typeof options == 'string') options = { + color: options, + transparent: true + }; + // add remove transarent color + if (options.transparent && pal[0][1] == '555555') { + pal[0].splice(1, 1); + pal[0].push(''); + } + if (!options.transparent && pal[0][1] != '555555') { + pal[0].splice(1, 0, '555555'); + pal[0].pop(); + } + if (options.color) options.color = String(options.color).toUpperCase(); + + if ($('#w2ui-overlay').length === 0) { + $(el).w2overlay(getColorHTML(options), { + onHide: function () { + if (typeof callBack == 'function') callBack($(el).data('_color')); + $(el).removeData('_color'); + } + }); + } else { // only refresh contents + $('#w2ui-overlay .w2ui-color').parent().html(getColorHTML(options)); + } + // bind events + $('#w2ui-overlay .color') + .off('.w2color') + .on('mousedown.w2color', function (event) { + var color = $(event.originalEvent.target).attr('name'); + index = $(event.originalEvent.target).attr('index').split(':'); + $(el).data('_color', color); + }) + .on('mouseup.w2color', function () { + setTimeout(function () { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); + }, 10); + }); + $('#w2ui-overlay input') + .off('.w2color') + .on('mousedown.w2color', function (event) { + $('#w2ui-overlay').data('keepOpen', true); + setTimeout(function () { $('#w2ui-overlay').data('keepOpen', true); }, 10); + event.stopPropagation(); + }) + .on('keyup.w2color', function (event) { + if (this.value !== '' && this.value[0] !== '#') this.value = '#' + this.value; + }) + .on('change.w2color', function (event) { + var tmp = this.value; + if (tmp.substr(0, 1) == '#') tmp = tmp.substr(1); + if (tmp.length != 6) { + $(this).w2tag('Invalid color.'); + return; + } + $.fn.w2colorPalette[pal.length - 1].unshift(tmp.toUpperCase()); + $(el).w2color(options, callBack); + setTimeout(function() { $('#w2ui-overlay input')[0].focus(); }, 100); + }) + .w2field('hex'); + + el.nav = function (direction) { + switch (direction) { + case 'up': + index[0]--; + break; + case 'down': + index[0]++; + break; + case 'right': + index[1]++; + break; + case 'left': + index[1]--; + break; + } + if (index[0] < 0) index[0] = 0; + if (index[0] > pal.length - 2) index[0] = pal.length - 2; + if (index[1] < 0) index[1] = 0; + if (index[1] > pal[0].length - 1) index[1] = pal[0].length - 1; + + color = pal[index[0]][index[1]]; + $(el).data('_color', color); + return color; + }; + + function getColorHTML(options) { + var color = options.color; + var html = '
'+ // prevent default is needed otherwiser selection gets unselected + ''; + for (var i = 0; i < pal.length - 1; i++) { + html += ''; + for (var j = 0; j < pal[i].length; j++) { + html += ''; + if (options.color == pal[i][j]) index = [i, j]; + } + html += ''; + if (i < 2) html += ''; + } + var tmp = pal[pal.length - 1]; + html += ''+ + ''+ + ' '+ + ' '+ + ' '+ + ' '+ + ' '+ + ''+ + ''; + html += '
'+ + '
'+ (options.color == pal[i][j] ? '•' : ' ') + + '
'+ + '
'+ (options.color == tmp[0] ? '•' : ' ') +'
'+ (options.color == tmp[1] ? '•' : ' ') +'
'+ (options.color == tmp[2] ? '•' : ' ') +'
'+ (options.color == tmp[3] ? '•' : ' ') +'
'; + return html; + } + }; + +})(jQuery); + +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2grid - grid widget +* - $().w2grid - jQuery wrapper +* - Dependencies: jQuery, w2utils, w2toolbar, w2fields +* +* == NICE TO HAVE == +* - column autosize based on largest content +* - reorder columns/records +* - problem with .set() and arrays, array get extended too, but should be replaced +* - after edit stay on the same record option +* - if supplied array of ids, get should return array of records +* - allow functions in routeData (also add routeData to list/enum) +* - implement global routeData and all elements read from there +* - send parsed URL to the event if there is routeData +* - if you set searchData or sortData and call refresh() it should work +* - add selectType: 'none' so that no selection can be make but with mouse +* - reorder records with frozen columns +* - focus/blur for selectType = cell not display grayed out selection +* - frozen columns + - load more only on the right side + - scrolling on frozen columns is not working only on regular columns +* - copy or large number of records is slow +* - reusable search component (see https://github.com/vitmalina/w2ui/issues/914#issuecomment-107340524) +* - allow enum in inline edit (see https://github.com/vitmalina/w2ui/issues/911#issuecomment-107341193) +* - if record has no recid, then it should be index in the aray (should not be 0) +* +* == KNOWN ISSUES == +* - bug: vs_start = 100 and more then 500 records, when scrolling empty sets +* - row drag and drop has bugs +* - Shift-click/Ctrl-click/Ctrl-Shift-Click selection is not as robust as it should be +* +* == 1.5 changes +* - $('#grid').w2grid() - if called w/o argument then it returns grid object +* - added statusRange : true, +* statusBuffered : false, +* statusRecordID : true, +* statusSelection : true, +* statusResponse : true, +* statusSort : true, +* statusSearch : true, +* - change selectAll() and selectNone() - return time it took +* - added vs_start and vs_extra +* - added update(cells) - updates only data in the grid (or cells) +* - add to docs onColumnDragStart, onColumnDragEnd +* - onSelect and onSelect should fire 1 time for selects with shift or selectAll(), selectNone() +* - record.w2ui.style[field_name] +* - use column field for style: { 1: 'color: red' } +* - added focus(), blur(), onFocus, onBlur +* - search.simple - if false, will not show up in simple search +* - search.operator - default operator to use with search field +* - search.operators - array of operators for the serach +* - search.hidden - could not be clearned by the user +* - search.value - only for hidden searches +* - if .search(val) - search all fields +* - refactor reorderRow (not finished) +* - return JSON can now have summary array +* - frozen columns +* - added selectionSave, selectionRestore - for internal use +* - added additional search filter options for int, float, date, time +* - added getLineHTML +* - added lineNumberWidth +* - add searches.style +* - getColumn without params returns fields of all columns +* - getSearch without params returns fields of all searches +* - added column.tooltip +* - added hasFocus, refactored w2utils.keyboard +* - do not clear selection when clicked and it was not in focus +* - added record.w2ui.colspan +* - editable area extends with typing +* - removed onSubmit and onDeleted - now it uses onSave and onDelete +* - column.seachable - can be an object, which will create search +* - added null, not null filters +* - update(cells) - added argument cells +* - scrollIntoView(..., ..., instant) - added third argument +* - added onResizeDblClick +* - added onColumnDblClick +* - implemented showBubble +* - added show.searchAll +* - added w2grid.operators +* - added w2grid.operatorsMap +* - move events into prototype +* - move rec.summary, rec.style, rec.editable -> into rec.w2ui.summary, rec.w2ui.style, rec.w2ui.editable +* - record: { + recid + field1 + ... + fieldN + w2ui: { + colspan: { field: 5, ...} + editable: true/false + changes: { + field: chagned_value, + .... + }, + children: [ + // similar to records array + // can have sub children + ] + parent_recid: (internally set, id of the parent record, when children are copied to records array) + summary: true/false + style: 'string' - for entire row OR { field: 'string', ...} - per field + class: 'string' - for entire row OR { field: 'string', ...} - per field + } + } +* - added this.show.toolbarInput +* - disableCVS +* - grid.message +* - added noReset option to localSort() +* - onColumnSelect +* - need to update PHP example +* - added scrollToColumn(field) +* - textSearch: 'begins' (default), 'contains', 'is', ... +* - added refreshBody +* - added response.total = -1 (or not present) to indicate that number of records is unknown +* - message(.., callBack) - added callBack +* - grid.msgEmpty +* - field.render(..., data) -- added last argument which is what grid thinks should be there +* - onSearchOpen (onSearch will have mutli and reset flags) +* - added httpHeaders +* - col.editable can be a function which will be called with the same args as col.render() +* - getCellEditable(index, col_ind) -- return an 'editable' descriptor if cell is really editable +* - added stateId +* - rec.w2ui.class (and rec.w2ui.class { fname: '...' }) +* - columnTooltip +* - expendable grids are still working +* - added search.type = 'color' +* +************************************************************************/ + +(function ($) { + var w2grid = function(options) { + + // public properties + this.name = null; + this.box = null; // HTML element that hold this element + this.header = ''; + this.url = ''; + this.routeData = {}; // data for dynamic routes + this.columns = []; // { field, caption, size, attr, render, hidden, gridMinWidth, editable } + this.columnGroups = []; // { span: int, caption: 'string', master: true/false } + this.records = []; // { recid: int(requied), field1: 'value1', ... fieldN: 'valueN', style: 'string', changes: object } + this.summary = []; // arry of summary records, same structure as records array + this.searches = []; // { type, caption, field, inTag, outTag, hidden } + this.searchData = []; + this.sortData = []; + this.postData = {}; + this.httpHeaders = {}; + this.toolbar = {}; // if not empty object; then it is toolbar object + this.stateId = null; // Custom state name for satateSave, stateRestore and stateReset + + this.show = { + header : false, + toolbar : false, + footer : false, + columnHeaders : true, + lineNumbers : false, + expandColumn : false, + selectColumn : false, + emptyRecords : true, + toolbarReload : true, + toolbarColumns : true, + toolbarSearch : true, + toolbarInput : true, + toolbarAdd : false, + toolbarEdit : false, + toolbarDelete : false, + toolbarSave : false, + searchAll : true, + statusRange : true, + statusBuffered : false, + statusRecordID : true, + statusSelection : true, + statusResponse : true, + statusSort : false, + statusSearch : false, + recordTitles : true, + selectionBorder : true, + skipRecords : true, + saveRestoreState: true + }; + + this.hasFocus = false; + this.autoLoad = true; // for infinite scroll + this.fixedBody = true; // if false; then grid grows with data + this.recordHeight = 24; // should be in prototype + this.lineNumberWidth = null; + this.vs_start = 150; + this.vs_extra = 15; + this.keyboard = true; + this.selectType = 'row'; // can be row|cell + this.multiSearch = true; + this.multiSelect = true; + this.multiSort = true; + this.reorderColumns = false; + this.reorderRows = false; + this.markSearch = true; + this.columnTooltip = 'normal'; // can be normal, top, bottom, left, right + this.disableCVS = false; // disable Column Virtual Scroll + this.textSearch = 'begins'; // default search type for text + + this.total = 0; // server total + this.limit = 100; + this.offset = 0; // how many records to skip (for infinite scroll) when pulling from server + this.style = ''; + this.ranges = []; + this.menu = []; + this.method = null; // if defined, then overwrited ajax method + this.recid = null; + this.parser = null; + + // internal + this.last = { + field : '', + caption : '', + logic : 'OR', + search : '', + searchIds : [], + selection : { + indexes : [], + columns : {} + }, + multi : false, + scrollTop : 0, + scrollLeft : 0, + colStart : 0, // for column virtual scrolling + colEnd : 0, + sortData : null, + sortCount : 0, + xhr : null, + range_start : null, + range_end : null, + sel_ind : null, + sel_col : null, + sel_type : null, + edit_col : null, + isSafari : (/^((?!chrome|android).)*safari/i).test(navigator.userAgent) + }; + + $.extend(true, this, w2obj.grid, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2grid = function(method) { + if ($.isPlainObject(method)) { + // check name parameter + if (!w2utils.checkName(method, 'w2grid')) return; + // remember items + var columns = method.columns; + var columnGroups = method.columnGroups; + var records = method.records; + var searches = method.searches; + var searchData = method.searchData; + var sortData = method.sortData; + var postData = method.postData; + var httpHeaders = method.httpHeaders; + var toolbar = method.toolbar; + // extend items + var object = new w2grid(method); + $.extend(object, { postData: {}, httpHeaders: {}, records: [], columns: [], searches: [], toolbar: {}, sortData: [], searchData: [], handlers: [] }); + if (object.onExpand != null) object.show.expandColumn = true; + $.extend(true, object.toolbar, toolbar); + // reassign variables + var p; + if (columns) for (p = 0; p < columns.length; p++) object.columns[p] = $.extend(true, {}, columns[p]); + if (columnGroups) for (p = 0; p < columnGroups.length; p++) object.columnGroups[p] = $.extend(true, {}, columnGroups[p]); + if (searches) for (p = 0; p < searches.length; p++) object.searches[p] = $.extend(true, {}, searches[p]); + if (searchData) for (p = 0; p < searchData.length; p++) object.searchData[p] = $.extend(true, {}, searchData[p]); + if (sortData) for (p = 0; p < sortData.length; p++) object.sortData[p] = $.extend(true, {}, sortData[p]); + object.postData = $.extend(true, {}, postData); + object.httpHeaders = $.extend(true, {}, httpHeaders); + + // check if there are records without recid + if (records) for (var r = 0; r < records.length; r++) { + if (records[r].recid == null && records[r][object.recid] == null) { + console.log('ERROR: Cannot add records without recid. (obj: '+ object.name +')'); + return; + } + object.records[r] = $.extend(true, {}, records[r]); + } + // add searches + for (var i = 0; i < object.columns.length; i++) { + var col = object.columns[i]; + var search = col.searchable; + if (search == null || search === false || object.getSearch(col.field) != null) continue; + if ($.isPlainObject(search)) { + object.addSearch($.extend({ field: col.field, caption: col.caption, type: 'text' }, search)); + } else { + var stype = col.searchable, attr = ''; + if (col.searchable === true) { stype = 'text'; attr = 'size="20"'; } + object.addSearch({ field: col.field, caption: col.caption, type: stype, attr: attr }); + } + } + // init toolbar + object.initToolbar(); + // render if necessary + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + 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 + + w2grid.prototype = { + msgDelete : 'Are you sure you want to delete selected records?', + msgNotJSON : 'Returned data is not in valid JSON format.', + msgAJAXerror : 'AJAX error. See console for more details.', + msgRefresh : 'Refreshing...', + msgNeedReload : 'Your remote data source record count has changed, reloading from the first record.', + msgEmpty : '', // if not blank, then it is message when server returns no records + + buttons: { + 'reload' : { type: 'button', id: 'w2ui-reload', icon: 'w2ui-icon-reload', tooltip: 'Reload data in the list' }, + 'columns' : { type: 'drop', id: 'w2ui-column-on-off', icon: 'w2ui-icon-columns', tooltip: 'Show/hide columns', arrow: false, html: '' }, + 'search' : { type: 'html', id: 'w2ui-search', + html: '
' + }, + 'search-go': { type: 'drop', id: 'w2ui-search-advanced', icon: 'w2ui-icon-search', text: 'Search', tooltip: 'Open Search Fields' }, + 'add' : { type: 'button', id: 'w2ui-add', text: 'Add New', tooltip: 'Add new record', icon: 'w2ui-icon-plus' }, + 'edit' : { type: 'button', id: 'w2ui-edit', text: 'Edit', tooltip: 'Edit selected record', icon: 'w2ui-icon-pencil', disabled: true }, + 'delete' : { type: 'button', id: 'w2ui-delete', text: 'Delete', tooltip: 'Delete selected records', icon: 'w2ui-icon-cross', disabled: true }, + 'save' : { type: 'button', id: 'w2ui-save', text: 'Save', tooltip: 'Save changed records', icon: 'w2ui-icon-check' } + }, + + operators: { // for search fields + "text" : ['is', 'begins', 'contains', 'ends'], + "number" : ['is', 'between', { oper: 'less', text: 'less than'}, { oper: 'more', text: 'more than' }], + "date" : ['is', 'between', { oper: 'less', text: 'before'}, { oper: 'more', text: 'after' }], + "list" : ['is'], + "hex" : ['is', 'between'], + "color" : ['is', 'begins', 'contains', 'ends'], + "enum" : ['in', 'not in'] + // -- all posible + // "text" : ['is', 'begins', 'contains', 'ends'], + // "number" : ['is', 'between', 'less:less than', 'more:more than', 'null:is null', 'not null:is not null'], + // "list" : ['is', 'null:is null', 'not null:is not null'], + // "enum" : ['in', 'not in', 'null:is null', 'not null:is not null'] + }, + + operatorsMap: { + "text" : "text", + "int" : "number", + "float" : "number", + "money" : "number", + "currency" : "number", + "percent" : "number", + "hex" : "hex", + "alphanumeric" : "text", + "color" : "color", + "date" : "date", + "time" : "date", + "datetime" : "date", + "list" : "list", + "combo" : "text", + "enum" : "enum", + "file" : "enum", + "select" : "list", + "radio" : "list", + "checkbox" : "list", + "toggle" : "list" + }, + + // events + onAdd : null, + onEdit : null, + onRequest : null, // called on any server event + onLoad : null, + onDelete : null, + onSave : null, + onSelect : null, + onUnselect : null, + onClick : null, + onDblClick : null, + onContextMenu : null, + onMenuClick : null, // when context menu item selected + onColumnClick : null, + onColumnDblClick : null, + onColumnResize : null, + onSort : null, + onSearch : null, + onSearchOpen : null, + onChange : null, // called when editable record is changed + onRestore : null, // called when editable record is restored + onExpand : null, + onCollapse : null, + onError : null, + onKeydown : null, + onToolbar : null, // all events from toolbar + onColumnOnOff : null, + onCopy : null, + onPaste : null, + onSelectionExtend : null, + onEditField : null, + onRender : null, + onRefresh : null, + onReload : null, + onResize : null, + onDestroy : null, + onStateSave : null, + onStateRestore : null, + onFocus : null, + onBlur : null, + onReorderRow : null, + + add: function (record, first) { + if (!$.isArray(record)) record = [record]; + var added = 0; + for (var i = 0; i < record.length; i++) { + var rec = record[i]; + if (rec.recid == null && rec[this.recid] == null) { + console.log('ERROR: Cannot add record without recid. (obj: '+ this.name +')'); + continue; + } + if (rec.w2ui && rec.w2ui.summary === true) { + if (first) this.summary.unshift(rec); else this.summary.push(rec); + } else { + if (first) this.records.unshift(rec); else this.records.push(rec); + } + added++; + } + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.total = this.records.length; + this.localSort(false, true); + this.localSearch(); + // do not call this.refresh(), this is unnecessary, heavy, and messes with the toolbar. + this.refreshBody(); + this.resizeRecords(); + return added; + } + this.refresh(); // ?? should it be reload? + return added; + }, + + find: function (obj, returnIndex) { + if (obj == null) obj = {}; + var recs = []; + var hasDots = false; + // check if property is nested - needed for speed + for (var o in obj) if (String(o).indexOf('.') != -1) hasDots = true; + // look for an item + for (var i = 0; i < this.records.length; i++) { + var match = true; + for (var o in obj) { + var val = this.records[i][o]; + if (hasDots && String(o).indexOf('.') != -1) val = this.parseField(this.records[i], o); + if (obj[o] == 'not-null') { + if (val == null || val === '') match = false; + } else { + if (obj[o] != val) match = false; + } + } + if (match && returnIndex !== true) recs.push(this.records[i].recid); + if (match && returnIndex === true) recs.push(i); + } + return recs; + }, + + set: function (recid, record, noRefresh) { // does not delete existing, but overrides on top of it + if (typeof recid == 'object') { + noRefresh = record; + record = recid; + recid = null; + } + // update all records + if (recid == null) { + for (var i = 0; i < this.records.length; i++) { + $.extend(true, this.records[i], record); // recid is the whole record + } + if (noRefresh !== true) this.refresh(); + } else { // find record to update + var ind = this.get(recid, true); + if (ind == null) return false; + var isSummary = (this.records[ind] && this.records[ind].recid == recid ? false : true); + if (isSummary) { + $.extend(true, this.summary[ind], record); + } else { + $.extend(true, this.records[ind], record); + } + if (noRefresh !== true) this.refreshRow(recid, ind); // refresh only that record + } + return true; + }, + + get: function (recid, returnIndex) { + // search records + if ($.isArray(recid)) { + var recs = []; + for (var i = 0; i < this.records.length; i++) { + if ($.inArray(this.records[i].recid, recid) != -1) { + if (returnIndex === true) { + recs.push(i); + } else { + recs.push(this.records[i]); + } + } + } + for (var i = 0; i < this.summary.length; i++) { + if ($.inArray(this.summary[i].recid, recid) != -1) { + if (returnIndex === true) { + recs.push(i); + } else { + recs.push(this.summary[i]); + } + } + } + return recs; + } else { + for (var i = 0; i < this.records.length; i++) { + if (this.records[i].recid == recid) { + if (returnIndex === true) return i; else return this.records[i]; + } + } + // search summary + for (var i = 0; i < this.summary.length; i++) { + if (this.summary[i].recid == recid) { + if (returnIndex === true) return i; else return this.summary[i]; + } + } + return null; + } + }, + + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.records.length-1; r >= 0; r--) { + if (this.records[r].recid == arguments[a]) { this.records.splice(r, 1); removed++; } + } + for (var r = this.summary.length-1; r >= 0; r--) { + if (this.summary[r].recid == arguments[a]) { this.summary.splice(r, 1); removed++; } + } + } + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.localSort(false, true); + this.localSearch(); + } + this.refresh(); + return removed; + }, + + addColumn: function (before, columns) { + var added = 0; + if (arguments.length == 1) { + columns = before; + before = this.columns.length; + } else { + if (typeof before == 'string') before = this.getColumn(before, true); + if (before == null) before = this.columns.length; + } + if (!$.isArray(columns)) columns = [columns]; + for (var i = 0; i < columns.length; i++) { + this.columns.splice(before, 0, columns[i]); + // if column is searchable, add search field + if (columns[i].searchable) { + var stype = columns[i].searchable; + var attr = ''; + if (columns[i].searchable === true) { stype = 'text'; attr = 'size="20"'; } + this.addSearch({ field: columns[i].field, caption: columns[i].caption, type: stype, attr: attr }); + } + before++; + added++; + } + this.refresh(); + return added; + }, + + removeColumn: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a]) { + if (this.columns[r].searchable) this.removeSearch(arguments[a]); + this.columns.splice(r, 1); + removed++; + } + } + } + this.refresh(); + return removed; + }, + + getColumn: function (field, returnIndex) { + // no arguments - return fields of all columns + if (arguments.length === 0) { + var ret = []; + for (var i = 0; i < this.columns.length; i++) ret.push(this.columns[i].field); + return ret; + } + // find column + for (var i = 0; i < this.columns.length; i++) { + if (this.columns[i].field == field) { + if (returnIndex === true) return i; else return this.columns[i]; + } + } + return null; + }, + + toggleColumn: function () { + var effected = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + var col = this.columns[r]; + if (col.field == arguments[a]) { + col.hidden = !col.hidden; + effected++; + } + } + } + this.refreshBody(); + this.resizeRecords(); + return effected; + }, + + showColumn: function () { + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + var col = this.columns[r]; + if (col.gridMinWidth) delete col.gridMinWidth; + if (col.field == arguments[a] && col.hidden !== false) { + col.hidden = false; + shown++; + } + } + } + this.refreshBody(); + this.resizeRecords(); + return shown; + }, + + hideColumn: function () { + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + var col = this.columns[r]; + if (col.field == arguments[a] && col.hidden !== true) { + col.hidden = true; + hidden++; + } + } + } + this.refreshBody(); + this.resizeRecords(); + return hidden; + }, + + addSearch: function (before, search) { + var added = 0; + if (arguments.length == 1) { + search = before; + before = this.searches.length; + } else { + if (typeof before == 'string') before = this.getSearch(before, true); + if (before == null) before = this.searches.length; + } + if (!$.isArray(search)) search = [search]; + for (var i = 0; i < search.length; i++) { + this.searches.splice(before, 0, search[i]); + before++; + added++; + } + this.searchClose(); + return added; + }, + + removeSearch: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { this.searches.splice(r, 1); removed++; } + } + } + this.searchClose(); + return removed; + }, + + getSearch: function (field, returnIndex) { + // no arguments - return fields of all searches + if (arguments.length === 0) { + var ret = []; + for (var i = 0; i < this.searches.length; i++) ret.push(this.searches[i].field); + return ret; + } + // find search + for (var i = 0; i < this.searches.length; i++) { + if (this.searches[i].field == field) { + if (returnIndex === true) return i; else return this.searches[i]; + } + } + return null; + }, + + toggleSearch: function () { + var effected = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { + this.searches[r].hidden = !this.searches[r].hidden; + effected++; + } + } + } + this.searchClose(); + return effected; + }, + + showSearch: function () { + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== false) { + this.searches[r].hidden = false; + shown++; + } + } + } + this.searchClose(); + return shown; + }, + + hideSearch: function () { + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== true) { + this.searches[r].hidden = true; + hidden++; + } + } + } + this.searchClose(); + return hidden; + }, + + getSearchData: function (field) { + for (var i = 0; i < this.searchData.length; i++) { + if (this.searchData[i].field == field) return this.searchData[i]; + } + return null; + }, + + localSort: function (silent, noResetRefresh) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + console.log('ERROR: grid.localSort can only be used on local data source, grid.url should be empty.'); + return; + } + if ($.isEmptyObject(this.sortData)) return; + var time = (new Date()).getTime(); + var obj = this; + // process date fields + obj.selectionSave(); + obj.prepareData(); + if (!noResetRefresh) { + obj.reset(); + } + // process sortData + for (var i = 0; i < this.sortData.length; i++) { + var column = this.getColumn(this.sortData[i].field); + if (!column) return; + if (typeof column.render == 'string') { + if (['date', 'age'].indexOf(column.render.split(':')[0]) != -1) { + this.sortData[i]['field_'] = column.field + '_'; + } + if (['time'].indexOf(column.render.split(':')[0]) != -1) { + this.sortData[i]['field_'] = column.field + '_'; + } + } + } + + // prepare paths and process sort + preparePaths(); + this.records.sort(function (a, b) { + return compareRecordPaths(a, b); + }); + cleanupPaths(); + + obj.selectionRestore(noResetRefresh); + time = (new Date()).getTime() - time; + if (silent !== true && obj.show.statusSort) { + setTimeout(function () { + obj.status(w2utils.lang('Sorting took') + ' ' + time/1000 + ' ' + w2utils.lang('sec')); + }, 10); + } + return time; + + // grab paths before sorting for efficiency and because calling obj.get() + // while sorting 'obj.records' is unsafe, at least on webkit + function preparePaths() { + for (var i = 0; i < obj.records.length; i++) { + var rec = obj.records[i]; + if (rec.w2ui && rec.w2ui.parent_recid != null) + rec.w2ui._path = getRecordPath(rec); + } + } + + // cleanup and release memory allocated by preparePaths() + function cleanupPaths() { + for (var i = 0; i < obj.records.length; i++) { + var rec = obj.records[i]; + if (rec.w2ui && rec.w2ui.parent_recid != null) + rec.w2ui._path = null; + } + } + + // compare two paths, from root of tree to given records + function compareRecordPaths(a, b) { + if ((!a.w2ui || a.w2ui.parent_recid == null) && (!b.w2ui || b.w2ui.parent_recid == null)) { + return compareRecords(a, b); // no tree, fast path + } + var pa = getRecordPath(a); + var pb = getRecordPath(b); + for (var i = 0; i < Math.min(pa.length, pb.length); i++) { + var diff = compareRecords(pa[i], pb[i]); + if (diff !== 0) return diff; // different subpath + } + if (pa.length > pb.length) return 1; + if (pa.length < pb.length) return -1; + console.log('ERROR: two paths should not be equal.'); + return 0; + } + + // return an array of all records from root to and including 'rec' + function getRecordPath(rec) { + if (!rec.w2ui || rec.w2ui.parent_recid == null) return [rec]; + if (rec.w2ui._path) + return rec.w2ui._path; + // during actual sort, we should never reach this point + var subrec = obj.get(rec.w2ui.parent_recid); + if (!subrec) { + console.log('ERROR: no parent record: '+rec.w2ui.parent_recid); + return [rec]; + } + return (getRecordPath(subrec).concat(rec)); + } + + // compare two records according to sortData and finally recid + function compareRecords(a, b) { + if (a === b) return 0; // optimize, same object + for (var i = 0; i < obj.sortData.length; i++) { + var fld = obj.sortData[i].field; + if (obj.sortData[i].field_) fld = obj.sortData[i].field_; + var aa = a[fld]; + var bb = b[fld]; + if (String(fld).indexOf('.') != -1) { + aa = obj.parseField(a, fld); + bb = obj.parseField(b, fld); + } + var col = obj.getColumn(fld); + if (col && col.editable != null) { // for drop editable fields and drop downs + if ($.isPlainObject(aa) && aa.text) aa = aa.text; + if ($.isPlainObject(bb) && bb.text) bb = bb.text; + } + var ret = compareCells(aa, bb, i, obj.sortData[i].direction); + if (ret !== 0) return ret; + } + // break tie for similar records, + // required to have consistent ordering for tree paths + var ret = compareCells(a.recid, b.recid, -1, 'asc'); + if (ret !== 0) return ret; + return 0; + } + + // compare two values, aa and bb, producing consistent ordering + function compareCells(aa, bb, i, direction) { + // if both objects are strictly equal, we're done + if (aa === bb) + return 0; + // all nulls, empty and undefined on bottom + if ((aa == null || aa === "") && (bb != null && bb !== "")) + return 1; + if ((aa != null && aa !== "") && (bb == null || bb === "")) + return -1; + var dir = (direction == 'asc') ? 1 : -1; + // for different kind of objects, sort by object type + if (typeof aa != typeof bb) + return (typeof aa > typeof bb) ? dir : -dir; + // for different kind of classes, sort by classes + if (aa.constructor.name != bb.constructor.name) + return (aa.constructor.name > bb.constructor.name) ? dir : -dir; + // if we're dealing with non-null objects, call valueOf(). + // this mean that Date() or custom objects will compare properly. + if (aa && typeof aa == 'object') + aa = aa.valueOf(); + if (bb && typeof bb == 'object') + bb = bb.valueOf(); + // if we're still dealing with non-null objects that have + // a useful Object => String conversion, convert to string. + var defaultToString = {}.toString; + if (aa && typeof aa == 'object' && aa.toString != defaultToString) + aa = String(aa); + if (bb && typeof bb == 'object' && bb.toString != defaultToString) + bb = String(bb); + // do case-insensitive string comparaison + if (typeof aa == 'string') + aa = $.trim(aa.toLowerCase()); + if (typeof bb == 'string') + bb = $.trim(bb.toLowerCase()); + // compare both objects + if (aa > bb) + return dir; + if (aa < bb) + return -dir; + return 0; + } + }, + + localSearch: function (silent) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + console.log('ERROR: grid.localSearch can only be used on local data source, grid.url should be empty.'); + return; + } + var time = (new Date()).getTime(); + var obj = this; + var defaultToString = {}.toString; + var duplicateMap = {}; + this.total = this.records.length; + // mark all records as shown + this.last.searchIds = []; + // prepare date/time fields + this.prepareData(); + // hide records that did not match + if (this.searchData.length > 0 && !url) { + this.total = 0; + for (var i = 0; i < this.records.length; i++) { + var rec = this.records[i]; + var match = searchRecord(rec); + if (match) { + if (rec && rec.w2ui) + addParent(rec.w2ui.parent_recid); + this.last.searchIds.push(i); + } + } + this.total = this.last.searchIds.length; + } + time = (new Date()).getTime() - time; + if (silent !== true && obj.show.statusSearch) { + setTimeout(function () { + obj.status(w2utils.lang('Search took') + ' ' + time/1000 + ' ' + w2utils.lang('sec')); + }, 10); + } + return time; + + // check if a record (or one of its closed children) matches the search data + function searchRecord(rec) { + var fl = 0; + for (var j = 0; j < obj.searchData.length; j++) { + var sdata = obj.searchData[j]; + var search = obj.getSearch(sdata.field); + if (sdata == null) continue; + if (search == null) search = { field: sdata.field, type: sdata.type }; + var val1b = obj.parseField(rec, search.field); + var val1 = (val1b !== null && val1b !== undefined && + (typeof val1b != "object" || val1b.toString != defaultToString)) ? + String(val1b).toLowerCase() : ""; // do not match a bogus string + if (sdata.value != null) { + if (!$.isArray(sdata.value)) { + var val2 = String(sdata.value).toLowerCase(); + } else { + var val2 = sdata.value[0]; + var val3 = sdata.value[1]; + } + } + switch (sdata.operator) { + case 'is': + if (obj.parseField(rec, search.field) == sdata.value) fl++; // do not hide record + else if (search.type == 'date') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatDate(tmp, 'yyyy-mm-dd'); + var val2 = w2utils.formatDate(w2utils.isDate(val2, w2utils.settings.dateFormat, true), 'yyyy-mm-dd'); + if (val1 == val2) fl++; + } + else if (search.type == 'time') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatTime(tmp, 'hh24:mi'); + var val2 = w2utils.formatTime(val2, 'hh24:mi'); + if (val1 == val2) fl++; + } + else if (search.type == 'datetime') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss'); + var val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss'); + if (val1 == val2) fl++; + } + break; + case 'between': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + if (parseFloat(obj.parseField(rec, search.field)) >= parseFloat(val2) && parseFloat(obj.parseField(rec, search.field)) <= parseFloat(val3)) fl++; + } + else if (search.type == 'date') { + var val1 = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val2 = w2utils.isDate(val2, w2utils.settings.dateFormat, true); + var val3 = w2utils.isDate(val3, w2utils.settings.dateFormat, true); + if (val3 != null) val3 = new Date(val3.getTime() + 86400000); // 1 day + if (val1 >= val2 && val1 < val3) fl++; + } + else if (search.type == 'time') { + var val1 = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val2 = w2utils.isTime(val2, true); + var val3 = w2utils.isTime(val3, true); + val2 = (new Date()).setHours(val2.hours, val2.minutes, val2.seconds ? val2.seconds : 0, 0); + val3 = (new Date()).setHours(val3.hours, val3.minutes, val3.seconds ? val3.seconds : 0, 0); + if (val1 >= val2 && val1 < val3) fl++; + } + else if (search.type == 'datetime') { + var val1 = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val2 = w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true); + var val3 = w2utils.isDateTime(val3, w2utils.settings.datetimeFormat, true); + if (val3) val3 = new Date(val3.getTime() + 86400000); // 1 day + if (val1 >= val2 && val1 < val3) fl++; + } + break; + case 'less': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + if (parseFloat(obj.parseField(rec, search.field)) <= parseFloat(sdata.value)) fl++; + } + else if (search.type == 'date') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatDate(tmp, 'yyyy-mm-dd'); + var val2 = w2utils.formatDate(w2utils.isDate(val2, w2utils.settings.dateFormat, true), 'yyyy-mm-dd'); + if (val1 <= val2) fl++; + } + else if (search.type == 'time') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatTime(tmp, 'hh24:mi'); + var val2 = w2utils.formatTime(val2, 'hh24:mi'); + if (val1 <= val2) fl++; + } + else if (search.type == 'datetime') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss'); + var val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss'); + if ( (val1.length == val2.length) && (val1 <= val2) ) fl++; + } + break; + case 'more': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + if (parseFloat(obj.parseField(rec, search.field)) >= parseFloat(sdata.value)) fl++; + } + else if (search.type == 'date') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatDate(tmp, 'yyyy-mm-dd'); + var val2 = w2utils.formatDate(w2utils.isDate(val2, w2utils.settings.dateFormat, true), 'yyyy-mm-dd'); + if (val1 >= val2) fl++; + } + else if (search.type == 'time') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatTime(tmp, 'hh24:mi'); + var val2 = w2utils.formatTime(val2, 'hh24:mi'); + if (val1 >= val2) fl++; + } + else if (search.type == 'datetime') { + var tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)); + var val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss'); + var val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss'); + if ( (val1.length == val2.length) && (val1 >= val2) ) fl++; + } + break; + case 'in': + var tmp = sdata.value; + if (sdata.svalue) tmp = sdata.svalue; + if (tmp.indexOf(w2utils.isFloat(val1) ? parseFloat(val1) : val1) !== -1) fl++; + if (tmp.indexOf(w2utils.isFloat(val1b) ? parseFloat(val1b) : val1b) !== -1) fl++; + break; + case 'not in': + var tmp = sdata.value; + if (sdata.svalue) tmp = sdata.svalue; + if (tmp.indexOf(w2utils.isFloat(val1) ? parseFloat(val1) : val1) == -1) fl++; + if (tmp.indexOf(w2utils.isFloat(val1b) ? parseFloat(val1b) : val1b) == -1) fl++; + break; + case 'begins': + case 'begins with': // need for back compatib. + if (val1.indexOf(val2) === 0) fl++; // do not hide record + break; + case 'contains': + if (val1.indexOf(val2) >= 0) fl++; // do not hide record + break; + case 'null': + if (obj.parseField(rec, search.field) == null) fl++; // do not hide record + break; + case 'not null': + if (obj.parseField(rec, search.field) != null) fl++; // do not hide record + break; + case 'ends': + case 'ends with': // need for back compatib. + var lastIndex = val1.lastIndexOf(val2); + if (lastIndex !== -1 && lastIndex == val1.length - val2.length) fl++; // do not hide record + break; + } + } + if ((obj.last.logic == 'OR' && fl !== 0) || + (obj.last.logic == 'AND' && fl == obj.searchData.length)) + return true; + if (rec.w2ui && rec.w2ui.children && rec.w2ui.expanded !== true) { + // there are closed children, search them too. + for (var r = 0; r < rec.w2ui.children.length; r++) { + var subRec = rec.w2ui.children[r]; + if (searchRecord(subRec)) + return true; + } + } + return false; + } + + // add parents nodes recursively + function addParent(recid) { + if (recid === undefined) + return; + if (duplicateMap[recid]) + return; // already visited + duplicateMap[recid] = true; + var i = obj.get(recid, true); + if (i == null) + return; + if ($.inArray(i, obj.last.searchIds) != -1) + return; + var rec = obj.records[i]; + if (rec && rec.w2ui) + addParent(rec.w2ui.parent_recid); + obj.last.searchIds.push(i); + } + }, + + getRangeData: function (range, extra) { + var rec1 = this.get(range[0].recid, true); + var rec2 = this.get(range[1].recid, true); + var col1 = range[0].column; + var col2 = range[1].column; + + var res = []; + if (col1 == col2) { // one row + for (var r = rec1; r <= rec2; r++) { + var record = this.records[r]; + var dt = record[this.columns[col1].field] || null; + if (extra !== true) { + res.push(dt); + } else { + res.push({ data: dt, column: col1, index: r, record: record }); + } + } + } else if (rec1 == rec2) { // one line + var record = this.records[rec1]; + for (var i = col1; i <= col2; i++) { + var dt = record[this.columns[i].field] || null; + if (extra !== true) { + res.push(dt); + } else { + res.push({ data: dt, column: i, index: rec1, record: record }); + } + } + } else { + for (var r = rec1; r <= rec2; r++) { + var record = this.records[r]; + res.push([]); + for (var i = col1; i <= col2; i++) { + var dt = record[this.columns[i].field]; + if (extra !== true) { + res[res.length-1].push(dt); + } else { + res[res.length-1].push({ data: dt, column: i, index: r, record: record }); + } + } + } + } + return res; + }, + + addRange: function (ranges) { + var added = 0; + if (this.selectType == 'row') return added; + if (!$.isArray(ranges)) ranges = [ranges]; + // if it is selection + for (var i = 0; i < ranges.length; i++) { + if (typeof ranges[i] != 'object') ranges[i] = { name: 'selection' }; + if (ranges[i].name == 'selection') { + if (this.show.selectionBorder === false) continue; + var sel = this.getSelection(); + if (sel.length === 0) { + this.removeRange('selection'); + continue; + } else { + var first = sel[0]; + var last = sel[sel.length-1]; + } + } else { // other range + var first = ranges[i].range[0]; + var last = ranges[i].range[1]; + } + if (first) { + var rg = { + name: ranges[i].name, + range: [{ recid: first.recid, column: first.column }, { recid: last.recid, column: last.column }], + style: ranges[i].style || '' + }; + // add range + var ind = false; + for (var j = 0; j < this.ranges.length; j++) if (this.ranges[j].name == ranges[i].name) { ind = j; break; } + if (ind !== false) { + this.ranges[ind] = rg; + } else { + this.ranges.push(rg); + } + added++; + } + } + this.refreshRanges(); + return added; + }, + + removeRange: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var name = arguments[a]; + $('#grid_'+ this.name +'_'+ name).remove(); + $('#grid_'+ this.name +'_f'+ name).remove(); + for (var r = this.ranges.length-1; r >= 0; r--) { + if (this.ranges[r].name == name) { + this.ranges.splice(r, 1); + removed++; + } + } + } + return removed; + }, + + refreshRanges: function () { + if (this.ranges.length === 0) return; + var obj = this; + var time = (new Date()).getTime(); + var rec1 = $('#grid_'+ this.name +'_frecords'); + var rec2 = $('#grid_'+ this.name +'_records'); + for (var i = 0; i < this.ranges.length; i++) { + var rg = this.ranges[i]; + var first = rg.range[0]; + var last = rg.range[1]; + if (first.index == null) first.index = this.get(first.recid, true); + if (last.index == null) last.index = this.get(last.recid, true); + var td1 = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) + ' td[col="'+ first.column +'"]'); + var td2 = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(last.recid) + ' td[col="'+ last.column +'"]'); + var td1f = $('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(first.recid) + ' td[col="'+ first.column +'"]'); + var td2f = $('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(last.recid) + ' td[col="'+ last.column +'"]'); + var _lastColumn = last.column; + // adjustment due to column virtual scroll + if (first.column < this.last.colStart && last.column > this.last.colStart) { + td1 = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) + ' td[col="start"]'); + } + if (first.column < this.last.colEnd && last.column > this.last.colEnd) { + _lastColumn = '"end"'; + td2 = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(last.recid) + ' td[col="end"]'); + } + // if virtual scrolling kicked in + var index_top = parseInt($('#grid_'+ this.name +'_rec_top').next().attr('index')); + var index_bottom = parseInt($('#grid_'+ this.name +'_rec_bottom').prev().attr('index')); + var index_ftop = parseInt($('#grid_'+ this.name +'_frec_top').next().attr('index')); + var index_fbottom = parseInt($('#grid_'+ this.name +'_frec_bottom').prev().attr('index')); + if (td1.length === 0 && first.index < index_top && last.index > index_top) { + td1 = $('#grid_'+ this.name +'_rec_top').next().find('td[col='+ first.column +']'); + } + if (td2.length === 0 && last.index > index_bottom && first.index < index_bottom) { + td2 = $('#grid_'+ this.name +'_rec_bottom').prev().find('td[col='+ _lastColumn +']'); + } + if (td1f.length === 0 && first.index < index_ftop && last.index > index_ftop) { // frozen + td1f = $('#grid_'+ this.name +'_frec_top').next().find('td[col='+ first.column +']'); + } + if (td2f.length === 0 && last.index > index_fbottom && first.index < index_fbottom) { // frozen + td2f = $('#grid_'+ this.name +'_frec_bottom').prev().find('td[col='+ last.column +']'); + } + + // do not show selection cell if it is editable + var edit = $(this.box).find('#grid_'+ this.name + '_editable'); + var tmp = edit.find('.w2ui-input'); + var tmp1 = tmp.attr('recid'); + var tmp2 = tmp.attr('column'); + if (rg.name == 'selection' && rg.range[0].recid == tmp1 && rg.range[0].column == tmp2) continue; + + // frozen regular columns range + var $range = $('#grid_'+ this.name +'_f'+ rg.name); + if (td1f.length > 0 || td2f.length > 0) { + if ($range.length === 0) { + rec1.append('
'+ + (rg.name == 'selection' ? '
' : '')+ + '
'); + $range = $('#grid_'+ this.name +'_f'+ rg.name); + } else { + $range.attr('style', rg.style); + $range.find('.w2ui-selection-resizer').show(); + } + if (td2f.length === 0) { + td2f = $('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(last.recid) +' td:last-child'); + if (td2f.length === 0) td2f = $('#grid_'+ this.name +'_frec_bottom td:first-child'); + $range.css('border-right', '0px'); + $range.find('.w2ui-selection-resizer').hide(); + } + if (first.recid != null && last.recid != null && td1f.length > 0 && td2f.length > 0) { + var _left = (td1f.position().left - 1 + rec1.scrollLeft()); + var _top = (td1f.position().top - 1 + rec1.scrollTop()); + $range.show().css({ + left : (_left > 0 ? _left : 0) + 'px', + top : (_top > 0 ? _top : 0) + 'px', + width : (td2f.position().left - td1f.position().left + td2f.width() + 3) + 'px', + height : (td2f.position().top - td1f.position().top + td2f.height() + 3) + 'px' + }); + } else { + $range.hide(); + } + } else { + $range.hide(); + } + // regular columns range + var $range = $('#grid_'+ this.name +'_'+ rg.name); + if (td1.length > 0 || td2.length > 0) { + if ($range.length === 0) { + rec2.append('
'+ + (rg.name == 'selection' ? '
' : '')+ + '
'); + $range = $('#grid_'+ this.name +'_'+ rg.name); + } else { + $range.attr('style', rg.style); + } + if (td1.length === 0) { + td1 = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) +' td:first-child'); + if (td1.length === 0) td1 = $('#grid_'+ this.name +'_rec_top td:first-child'); + } + if (td2f.length !== 0) { + $range.css('border-left', '0px'); + } + if (first.recid != null && last.recid != null && td1.length > 0 && td2.length > 0) { + var _left = (td1.position().left - 1 + rec2.scrollLeft()); + var _top = (td1.position().top - 1 + rec2.scrollTop()); + $range.show().css({ + left : (_left > 0 ? _left : 0) + 'px', + top : (_top > 0 ? _top : 0) + 'px', + width : (td2.position().left - td1.position().left + td2.width() + 3) + 'px', + height : (td2.position().top - td1.position().top + td2.height() + 3) + 'px' + }); + } else { + $range.hide(); + } + } else { + $range.hide(); + } + } + + // add resizer events + $(this.box).find('.w2ui-selection-resizer') + .off('mousedown').on('mousedown', mouseStart) + .off('dblclick').on('dblclick', function (event) { + var edata = obj.trigger({ phase: 'before', type: 'resizerDblClick', target: obj.name, originalEvent: event }); + if (edata.isCancelled === true) return; + obj.trigger($.extend(edata, { phase: 'after' })); + }); + var edata = { phase: 'before', type: 'selectionExtend', target: obj.name, originalRange: null, newRange: null }; + + return (new Date()).getTime() - time; + + function mouseStart (event) { + var sel = obj.getSelection(); + obj.last.move = { + type : 'expand', + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + recid : sel[0].recid, + column : sel[0].column, + originalRange : [{ recid: sel[0].recid, column: sel[0].column }, { recid: sel[sel.length-1].recid, column: sel[sel.length-1].column }], + newRange : [{ recid: sel[0].recid, column: sel[0].column }, { recid: sel[sel.length-1].recid, column: sel[sel.length-1].column }] + }; + $(document).off('mousemove', mouseMove).on('mousemove', mouseMove); + $(document).off('mouseup', mouseStop).on('mouseup', mouseStop); + // do not blur grid + event.preventDefault(); + } + + function mouseMove (event) { + var mv = obj.last.move; + if (!mv || mv.type != 'expand') return; + mv.divX = (event.screenX - mv.x); + mv.divY = (event.screenY - mv.y); + // find new cell + var recid, column; + var tmp = event.originalEvent.target; + if (tmp.tagName.toUpperCase() != 'TD') tmp = $(tmp).parents('td')[0]; + if ($(tmp).attr('col') != null) column = parseInt($(tmp).attr('col')); + tmp = $(tmp).parents('tr')[0]; + recid = $(tmp).attr('recid'); + // new range + if (mv.newRange[1].recid == recid && mv.newRange[1].column == column) return; + var prevNewRange = $.extend({}, mv.newRange); + mv.newRange = [{ recid: mv.recid, column: mv.column }, { recid: recid, column: column }]; + // event before + edata = obj.trigger($.extend(edata, { originalRange: mv.originalRange, newRange : mv.newRange })); + if (edata.isCancelled === true) { + mv.newRange = prevNewRange; + edata.newRange = prevNewRange; + return; + } else { + // default behavior + obj.removeRange('grid-selection-expand'); + obj.addRange({ + name : 'grid-selection-expand', + range : edata.newRange, + style : 'background-color: rgba(100,100,100,0.1); border: 2px dotted rgba(100,100,100,0.5);' + }); + } + } + + function mouseStop (event) { + // default behavior + obj.removeRange('grid-selection-expand'); + delete obj.last.move; + $(document).off('mousemove', mouseMove); + $(document).off('mouseup', mouseStop); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + }, + + select: function () { + if (arguments.length === 0) return 0; + var time = (new Date).getTime(); + var selected = 0; + var sel = this.last.selection; + if (!this.multiSelect) this.selectNone(); + + // event before + var tmp = { phase: 'before', type: 'select', target: this.name }; + if (arguments.length == 1) { + tmp.multiple = false; + if ($.isPlainObject(arguments[0])) { + tmp.recid = arguments[0].recid; + tmp.column = arguments[0].column; + } else { + tmp.recid = arguments[0]; + } + } else { + tmp.multiple = true; + tmp.recids = Array.prototype.slice.call(arguments, 0); + } + var edata = this.trigger(tmp); + if (edata.isCancelled === true) return 0; + + // default action + if (this.selectType == 'row') { + for (var a = 0; a < arguments.length; a++) { + var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; + var index = this.get(recid, true); + if (index == null) continue; + var recEl1 = null; + var recEl2 = null; + if (this.searchData.length !== 0 || (index + 1 >= this.last.range_start && index + 1 <= this.last.range_end)) { + recEl1 = $('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)); + recEl2 = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + } + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) != -1) continue; + sel.indexes.push(index); + if (recEl1 && recEl2) { + recEl1.addClass('w2ui-selected').data('selected', 'yes').find('.w2ui-col-number').addClass('w2ui-row-selected'); + recEl2.addClass('w2ui-selected').data('selected', 'yes').find('.w2ui-col-number').addClass('w2ui-row-selected'); + recEl1.find('.w2ui-grid-select-check').prop("checked", true); + } + selected++; + } + } + } else { + // normalize for performance + var new_sel = {}; + for (var a = 0; a < arguments.length; a++) { + var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; + var column = typeof arguments[a] == 'object' ? arguments[a].column : null; + new_sel[recid] = new_sel[recid] || []; + if ($.isArray(column)) { + new_sel[recid] = column; + } else if (w2utils.isInt(column)) { + new_sel[recid].push(column); + } else { + for (var i = 0; i < this.columns.length; i++) { if (this.columns[i].hidden) continue; new_sel[recid].push(parseInt(i)); } + } + } + // add all + var col_sel = []; + for (var recid in new_sel) { + var index = this.get(recid, true); + if (index == null) continue; + var recEl1 = null; + var recEl2 = null; + if (index + 1 >= this.last.range_start && index + 1 <= this.last.range_end) { + recEl1 = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + recEl2 = $('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)); + } + var s = sel.columns[index] || []; + // default action + if (sel.indexes.indexOf(index) == -1) { + sel.indexes.push(index); + } + // anly only those that are new + for (var t = 0; t < new_sel[recid].length; t++) { + if (s.indexOf(new_sel[recid][t]) == -1) s.push(new_sel[recid][t]); + } + s.sort(function(a, b) { return a-b; }); // sort function must be for numerical sort + for (var t = 0; t < new_sel[recid].length; t++) { + var col = new_sel[recid][t]; + if (col_sel.indexOf(col) == -1) col_sel.push(col); + if (recEl1) { + recEl1.find('#grid_'+ this.name +'_data_'+ index +'_'+ col).addClass('w2ui-selected'); + recEl1.find('.w2ui-col-number').addClass('w2ui-row-selected'); + recEl1.data('selected', 'yes'); + recEl1.find('.w2ui-grid-select-check').prop("checked", true); + } + if (recEl2) { + recEl2.find('#grid_'+ this.name +'_data_'+ index +'_'+ col).addClass('w2ui-selected'); + recEl2.find('.w2ui-col-number').addClass('w2ui-row-selected'); + recEl2.data('selected', 'yes'); + recEl2.find('.w2ui-grid-select-check').prop("checked", true); + } + selected++; + } + // save back to selection object + sel.columns[index] = s; + } + // select columns (need here for speed) + for (var c = 0; c < col_sel.length; c++) { + $(this.box).find('#grid_'+ this.name +'_column_'+ col_sel[c] +' .w2ui-col-header').addClass('w2ui-col-selected'); + } + } + // need to sort new selection for speed + sel.indexes.sort(function(a, b) { return a-b; }); + // all selected? + var 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); + } + this.status(); + this.addRange('selection'); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return selected; + }, + + unselect: function () { + var unselected = 0; + var sel = this.last.selection; + for (var a = 0; a < arguments.length; a++) { + var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; + var record = this.get(recid); + if (record == null) continue; + var index = this.get(record.recid, true); + var recEl1 = $('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)); + var recEl2 = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) == -1) continue; + // event before + var edata = this.trigger({ phase: 'before', type: 'unselect', target: this.name, recid: recid, index: index }); + if (edata.isCancelled === true) continue; + // default action + sel.indexes.splice(sel.indexes.indexOf(index), 1); + recEl1.removeClass('w2ui-selected w2ui-inactive').removeData('selected').find('.w2ui-col-number').removeClass('w2ui-row-selected'); + recEl2.removeClass('w2ui-selected w2ui-inactive').removeData('selected').find('.w2ui-col-number').removeClass('w2ui-row-selected'); + if (recEl1.length != 0) { + recEl1[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl1.attr('custom_style'); + recEl2[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl2.attr('custom_style'); + } + recEl1.find('.w2ui-grid-select-check').prop("checked", false); + unselected++; + } else { + var col = arguments[a].column; + if (!w2utils.isInt(col)) { // unselect all columns + var cols = []; + for (var i = 0; i < this.columns.length; i++) { if (this.columns[i].hidden) continue; cols.push({ recid: recid, column: i }); } + return this.unselect.apply(this, cols); + } + var s = sel.columns[index]; + if (!$.isArray(s) || s.indexOf(col) == -1) continue; + // event before + var edata = this.trigger({ phase: 'before', type: 'unselect', target: this.name, recid: recid, column: col }); + if (edata.isCancelled === true) continue; + // default action + s.splice(s.indexOf(col), 1); + $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)).find(' > td[col='+ col +']').removeClass('w2ui-selected w2ui-inactive'); + $('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)).find(' > td[col='+ col +']').removeClass('w2ui-selected w2ui-inactive'); + // check if any row/column still selected + var isColSelected = false; + var isRowSelected = false; + var tmp = this.getSelection(); + for (var i = 0; i < tmp.length; i++) { + if (tmp[i].column == col) isColSelected = true; + if (tmp[i].recid == recid) isRowSelected = true; + } + if (!isColSelected) { + $(this.box).find('.w2ui-grid-columns td[col='+ col +'] .w2ui-col-header, .w2ui-grid-fcolumns td[col='+ col +'] .w2ui-col-header').removeClass('w2ui-col-selected'); + } + if (!isRowSelected) { + $('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)).find('.w2ui-col-number').removeClass('w2ui-row-selected'); + } + unselected++; + if (s.length === 0) { + delete sel.columns[index]; + sel.indexes.splice(sel.indexes.indexOf(index), 1); + recEl1.removeData('selected'); + recEl1.find('.w2ui-grid-select-check').prop("checked", false); + recEl2.removeData('selected'); + } + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + // all selected? + var 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(); + this.addRange('selection'); + return unselected; + }, + + selectAll: function () { + var time = (new Date()).getTime(); + if (this.multiSelect === false) return; + // event before + var edata = this.trigger({ phase: 'before', type: 'select', target: this.name, all: true }); + if (edata.isCancelled === true) return; + // default action + var url = (typeof this.url != 'object' ? this.url : this.url.get); + var sel = this.last.selection; + var cols = []; + for (var i = 0; i < this.columns.length; i++) cols.push(i); + // if local data source and searched + sel.indexes = []; + if (!url && this.searchData.length !== 0) { + // local search applied + for (var i = 0; i < this.last.searchIds.length; i++) { + sel.indexes.push(this.last.searchIds[i]); + if (this.selectType != 'row') sel.columns[this.last.searchIds[i]] = cols.slice(); // .slice makes copy of the array + } + } else { + var buffered = this.records.length; + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length; + for (var i = 0; i < buffered; i++) { + sel.indexes.push(i); + if (this.selectType != 'row') sel.columns[i] = cols.slice(); // .slice makes copy of the array + } + } + // add selected class + if (this.selectType == 'row') { + $(this.box).find('.w2ui-grid-records tr').not('.w2ui-empty-record') + .addClass('w2ui-selected').data('selected', 'yes').find('.w2ui-col-number').addClass('w2ui-row-selected'); + $(this.box).find('.w2ui-grid-frecords tr').not('.w2ui-empty-record') + .addClass('w2ui-selected').data('selected', 'yes').find('.w2ui-col-number').addClass('w2ui-row-selected'); + $(this.box).find('input.w2ui-grid-select-check').prop('checked', true); + } else { + $(this.box).find('.w2ui-grid-columns td .w2ui-col-header, .w2ui-grid-fcolumns td .w2ui-col-header').addClass('w2ui-col-selected'); + $(this.box).find('.w2ui-grid-records tr .w2ui-col-number').addClass('w2ui-row-selected'); + $(this.box).find('.w2ui-grid-records tr').not('.w2ui-empty-record') + .find('.w2ui-grid-data').not('.w2ui-col-select').addClass('w2ui-selected').data('selected', 'yes'); + $(this.box).find('.w2ui-grid-frecords tr .w2ui-col-number').addClass('w2ui-row-selected'); + $(this.box).find('.w2ui-grid-frecords tr').not('.w2ui-empty-record') + .find('.w2ui-grid-data').not('.w2ui-col-select').addClass('w2ui-selected').data('selected', 'yes'); + $(this.box).find('input.w2ui-grid-select-check').prop('checked', true); + } + // enable/disable toolbar buttons + var sel = this.getSelection(); + 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'); + this.addRange('selection'); + $('#grid_'+ this.name +'_check_all').prop('checked', true); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + selectNone: function () { + var time = (new Date()).getTime(); + // event before + var edata = this.trigger({ phase: 'before', type: 'unselect', target: this.name, all: true }); + if (edata.isCancelled === true) return; + // default action + var sel = this.last.selection; + // remove selected class + if (this.selectType == 'row') { + $(this.box).find('.w2ui-grid-records tr.w2ui-selected').removeClass('w2ui-selected w2ui-inactive').removeData('selected') + .find('.w2ui-col-number').removeClass('w2ui-row-selected'); + $(this.box).find('.w2ui-grid-frecords tr.w2ui-selected').removeClass('w2ui-selected w2ui-inactive').removeData('selected') + .find('.w2ui-col-number').removeClass('w2ui-row-selected'); + $(this.box).find('input.w2ui-grid-select-check').prop('checked', false); + } else { + $(this.box).find('.w2ui-grid-columns td .w2ui-col-header, .w2ui-grid-fcolumns td .w2ui-col-header').removeClass('w2ui-col-selected'); + $(this.box).find('.w2ui-grid-records tr .w2ui-col-number').removeClass('w2ui-row-selected'); + $(this.box).find('.w2ui-grid-frecords tr .w2ui-col-number').removeClass('w2ui-row-selected'); + $(this.box).find('.w2ui-grid-data.w2ui-selected').removeClass('w2ui-selected w2ui-inactive').removeData('selected'); + $(this.box).find('input.w2ui-grid-select-check').prop('checked', false); + } + sel.indexes = []; + sel.columns = {}; + this.toolbar.disable('w2ui-edit', 'w2ui-delete'); + this.removeRange('selection'); + $('#grid_'+ this.name +'_check_all').prop('checked', false); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + getSelection: function (returnIndex) { + var ret = []; + var sel = this.last.selection; + if (this.selectType == 'row') { + for (var i = 0; i < sel.indexes.length; i++) { + if (!this.records[sel.indexes[i]]) continue; + if (returnIndex === true) ret.push(sel.indexes[i]); else ret.push(this.records[sel.indexes[i]].recid); + } + return ret; + } else { + for (var i = 0; i < sel.indexes.length; i++) { + var cols = sel.columns[sel.indexes[i]]; + if (!this.records[sel.indexes[i]]) continue; + for (var j = 0; j < cols.length; j++) { + ret.push({ recid: this.records[sel.indexes[i]].recid, index: parseInt(sel.indexes[i]), column: cols[j] }); + } + } + return ret; + } + }, + + search: function (field, value) { + var obj = this; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + var searchData = []; + var last_multi = this.last.multi; + var last_logic = this.last.logic; + var last_field = this.last.field; + var last_search = this.last.search; + var hasHiddenSearches = false; + // add hidden searches + for (var i = 0; i < this.searches.length; i++) { + if (!this.searches[i].hidden) continue; + searchData.push({ + field : this.searches[i].field, + operator : this.searches[i].operator || 'is', + type : this.searches[i].type, + value : this.searches[i].value || '' + }); + hasHiddenSearches = true; + } + // 1: search() - advanced search (reads from popup) + if (arguments.length === 0) { + last_search = ''; + // advanced search + for (var i = 0; i < this.searches.length; i++) { + var search = this.searches[i]; + var operator = $('#grid_'+ this.name + '_operator_'+ i).val(); + var field1 = $('#grid_'+ this.name + '_field_'+ i); + var field2 = $('#grid_'+ this.name + '_field2_'+ i); + var value1 = field1.val(); + var value2 = field2.val(); + var svalue = null; + var text = null; + + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + var fld1 = field1.data('w2field'); + var fld2 = field2.data('w2field'); + if (fld1) value1 = fld1.clean(value1); + if (fld2) value2 = fld2.clean(value2); + } + if (['list', 'enum'].indexOf(search.type) != -1) { + value1 = field1.data('selected') || {}; + if ($.isArray(value1)) { + svalue = []; + for (var j = 0; j < value1.length; j++) { + svalue.push(w2utils.isFloat(value1[j].id) ? parseFloat(value1[j].id) : String(value1[j].id).toLowerCase()); + delete value1[j].hidden; + } + if ($.isEmptyObject(value1)) value1 = ''; + } else { + text = value1.text || ''; + value1 = value1.id || ''; + } + } + if ((value1 !== '' && value1 != null) || (value2 != null && value2 !== '')) { + var tmp = { + field : search.field, + type : search.type, + operator : operator + }; + if (operator == 'between') { + $.extend(tmp, { value: [value1, value2] }); + } else if (operator == 'in' && typeof value1 == 'string') { + $.extend(tmp, { value: value1.split(',') }); + } else if (operator == 'not in' && typeof value1 == 'string') { + $.extend(tmp, { value: value1.split(',') }); + } else { + $.extend(tmp, { value: value1 }); + } + if (svalue) $.extend(tmp, { svalue: svalue }); + if (text) $.extend(tmp, { text: text }); + + // conver date to unix time + try { + if (search.type == 'date' && operator == 'between') { + tmp.value[0] = value1; // w2utils.isDate(value1, w2utils.settings.dateFormat, true).getTime(); + tmp.value[1] = value2; // w2utils.isDate(value2, w2utils.settings.dateFormat, true).getTime(); + } + if (search.type == 'date' && operator == 'is') { + tmp.value = value1; // w2utils.isDate(value1, w2utils.settings.dateFormat, true).getTime(); + } + } catch (e) { + + } + searchData.push(tmp); + } + } + last_multi = true; + last_logic = 'AND'; + } + // 2: search(field, value) - regular search + if (typeof field == 'string') { + // if only one argument - search all + if (arguments.length == 1) { + value = field; + field = 'all'; + } + last_field = field; + last_search = value; + last_multi = false; + last_logic = (hasHiddenSearches ? 'AND' : 'OR'); + // loop through all searches and see if it applies + if (value != null) { + if (field.toLowerCase() == 'all') { + // if there are search fields loop thru them + if (this.searches.length > 0) { + for (var i = 0; i < this.searches.length; i++) { + var search = this.searches[i]; + if ( search.type == 'text' || (search.type == 'alphanumeric' && w2utils.isAlphaNumeric(value)) + || (search.type == 'int' && w2utils.isInt(value)) || (search.type == 'float' && w2utils.isFloat(value)) + || (search.type == 'percent' && w2utils.isFloat(value)) || ((search.type == 'hex' || search.type == 'color') && w2utils.isHex(value)) + || (search.type == 'currency' && w2utils.isMoney(value)) || (search.type == 'money' && w2utils.isMoney(value)) + || (search.type == 'date' && w2utils.isDate(value)) || (search.type == 'time' && w2utils.isTime(value)) + || (search.type == 'datetime' && w2utils.isDateTime(value)) || (search.type == 'enum' && w2utils.isAlphaNumeric(value)) + || (search.type == 'list' && w2utils.isAlphaNumeric(value)) + ) { + var tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : (search.type == 'text' ? this.textSearch : 'is')), + value : value + }; + if ($.trim(value) != '') searchData.push(tmp); + } + // range in global search box + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1 && $.trim(String(value)).split('-').length == 2) { + var t = $.trim(String(value)).split('-'); + var tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : 'between'), + value : [t[0], t[1]] + }; + searchData.push(tmp); + } + // lists fiels + if (['list', 'enum'].indexOf(search.type) != -1) { + var new_values = []; + for (var j = 0; j < search.options.items; j++) { + var tmp = search.options.items[j]; + try { + var re = new RegExp(value, 'i'); + if (re.test(tmp)) new_values.push(j); + if (tmp.text && re.test(tmp.text)) new_values.push(tmp.id); + } catch (e) {} + } + if (new_values.length > 0) { + var tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : 'in'), + value : new_values + }; + searchData.push(tmp); + } + } + } + } else { + // no search fields, loop thru columns + for (var i = 0; i < this.columns.length; i++) { + var tmp = { + field : this.columns[i].field, + type : 'text', + operator : this.textSearch, + value : value + }; + searchData.push(tmp); + } + } + } else { + var el = $('#grid_'+ this.name +'_search_all'); + var search = this.getSearch(field); + if (search == null) search = { field: field, type: 'text' }; + if (search.field == field) this.last.caption = search.caption; + if (value !== '') { + var op = this.textSearch; + var val = value; + if (['date', 'time', 'datetime'].indexOf(search.type) != -1) op = 'is'; + if (['list', 'enum'].indexOf(search.type) != -1) { + op = 'is'; + var tmp = el.data('selected'); + if (tmp && !$.isEmptyObject(tmp)) val = tmp.id; else val = ''; + } + if (search.type == 'int' && value !== '') { + op = 'is'; + if (String(value).indexOf('-') != -1) { + var tmp = value.split('-'); + if (tmp.length == 2) { + op = 'between'; + val = [parseInt(tmp[0]), parseInt(tmp[1])]; + } + } + if (String(value).indexOf(',') != -1) { + var tmp = value.split(','); + op = 'in'; + val = []; + for (var i = 0; i < tmp.length; i++) val.push(tmp[i]); + } + } + if (search.operator != null) op = search.operator; + var tmp = { + field : search.field, + type : search.type, + operator : op, + value : val + }; + searchData.push(tmp); + } + } + } + } + // 3: search([ { field, value, [operator,] [type] }, { field, value, [operator,] [type] } ], logic) - submit whole structure + if ($.isArray(field)) { + var logic = 'AND'; + if (typeof value == 'string') { + logic = value.toUpperCase(); + if (logic != 'OR' && logic != 'AND') logic = 'AND'; + } + last_search = ''; + last_multi = true; + last_logic = logic; + for (var i = 0; i < field.length; i++) { + var data = field[i]; + var search = this.getSearch(data.field); + if (search == null) search = { type: 'text', operator: 'begins' }; + if ($.isArray(data.value)) { + for (var j = 0; j < data.value.length; j++) { + if (typeof data.value[j] == 'string') data.value[j] = data.value[j].toLowerCase(); + } + } + // merge current field and search if any + searchData.push($.extend(true, {}, search, data)); + } + } + // event before + var edata = this.trigger({ phase: 'before', type: 'search', multi: (arguments.length === 0 ? true : false), target: this.name, searchData: searchData, + searchField: (field ? field : 'multi'), searchValue: (field ? value : 'multi') }); + if (edata.isCancelled === true) return; + // default action + this.searchData = edata.searchData; + this.last.field = last_field; + this.last.search = last_search; + this.last.multi = last_multi; + this.last.logic = last_logic; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection.indexes = []; + this.last.selection.columns = {}; + // -- clear all search field + this.searchClose(); + // apply search + if (url) { + this.last.xhr_offset = 0; + this.reload(); + } else { + // local search + this.localSearch(); + this.refresh(); + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + searchOpen: function () { + if (!this.box) return; + if (this.searches.length === 0) return; + var obj = this; + // event before + var edata = this.trigger({ phase: 'before', type: 'searchOpen', target: this.name }); + if (edata.isCancelled === true) { + setTimeout(function () { obj.toolbar.uncheck('w2ui-search-advanced'); }, 1); + return; + } + // show search + $('#tb_'+ this.name +'_toolbar_item_w2ui-search-advanced').w2overlay({ + html : this.getSearchesHTML(), + name : this.name + '-searchOverlay', + left : -10, + 'class' : 'w2ui-grid-searches', + onShow : function () { + obj.initSearches(); + $('#w2ui-overlay-'+ obj.name +'-searchOverlay .w2ui-grid-searches').data('grid-name', obj.name); + var sfields = $('#w2ui-overlay-'+ this.name +'-searchOverlay .w2ui-grid-searches *[rel=search]'); + if (sfields.length > 0) sfields[0].focus(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + }); + }, + + searchClose: function () { + var obj = this; + if (!this.box) return; + if (this.searches.length === 0) return; + if (this.toolbar) this.toolbar.uncheck('w2ui-search-advanced'); + // hide search + $().w2overlay({ name: this.name + '-searchOverlay' }); + $().w2overlay({ name: this.name + '-searchOverlay' }); // need to call twice as first ignored after click + }, + + searchReset: function (noRefresh) { + var searchData = []; + var hasHiddenSearches = false; + // add hidden searches + for (var i = 0; i < this.searches.length; i++) { + if (!this.searches[i].hidden) continue; + searchData.push({ + field : this.searches[i].field, + operator : this.searches[i].operator || 'is', + type : this.searches[i].type, + value : this.searches[i].value || '' + }); + hasHiddenSearches = true; + } + // event before + var edata = this.trigger({ phase: 'before', type: 'search', reset: true, target: this.name, searchData: searchData }); + if (edata.isCancelled === true) return; + // default action + this.searchData = edata.searchData; + this.last.search = ''; + this.last.logic = (hasHiddenSearches ? 'AND' : 'OR'); + // --- do not reset to All Fields (I think) + if (this.searches.length > 0) { + 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.caption = ''; + } else { + this.last.field = this.searches[tmp].field; + this.last.caption = this.searches[tmp].caption; + } + } else { + this.last.field = 'all'; + this.last.caption = w2utils.lang('All Fields'); + } + } + this.last.multi = false; + this.last.xhr_offset = 0; + // reset scrolling position + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection.indexes = []; + this.last.selection.columns = {}; + // -- clear all search field + this.searchClose(); + $('#grid_'+ this.name +'_search_all').val('').removeData('selected'); + // apply search + if (!noRefresh) this.reload(); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + searchShowFields: function () { + var obj = this; + var el = $('#grid_'+ this.name +'_search_all'); + var html = '
'; + for (var s = -1; s < this.searches.length; s++) { + var search = this.searches[s]; + if (s == -1) { + if (!this.multiSearch || !this.show.searchAll) continue; + search = { field: 'all', caption: w2utils.lang('All Fields') }; + } else { + if (this.searches[s].hidden === true || this.searches[s].simple === false) continue; + } + html += ''+ + ' '+ + ' '+ + ''; + } + html += "
'+ + ' '+ + ' '+ search.caption +'
"; + // need timer otherwise does nto show with list type + setTimeout(function () { + $(el).w2overlay({ html: html, name: obj.name + '-searchFields', left: -10 }); + }, 1); + }, + + initAllField: function (field, value) { + var el = $('#grid_'+ this.name +'_search_all'); + if (field == 'all') { + var search = { field: 'all', caption: w2utils.lang('All Fields') }; + el.w2field('clear'); + el.change(); + } else { + var search = this.getSearch(field); + if (search == null) return; + var st = search.type; + if (['enum', 'select'].indexOf(st) != -1) st = 'list'; + el.w2field(st, $.extend({}, search.options, { suffix: '', autoFormat: false, selected: value })); + if (['list', 'enum', 'date', 'time', 'datetime'].indexOf(search.type) != -1) { + this.last.search = ''; + this.last.item = ''; + el.val(''); + } + } + // update field + if (this.last.search != '') { + this.last.caption = search.caption; + this.search(search.field, this.last.search); + } else { + this.last.field = search.field; + this.last.caption = search.caption; + } + el.attr('placeholder', w2utils.lang(search.caption)); + $().w2overlay({ name: this.name + '-searchFields' }); + }, + + // clears records and related params + clear: function (noRefresh) { + this.total = 0; + this.records = []; + this.summary = []; + this.last.xhr_offset = 0; // need this for reload button to work on remote data set + this.reset(true); + // refresh + if (!noRefresh) this.refresh(); + }, + + // clears scroll position, selection, ranges + reset: function (noRefresh) { + // position + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection = { indexes: [], columns: {} }; + this.last.range_start = null; + this.last.range_end = null; + // additional + $('#grid_'+ this.name +'_records').prop('scrollTop', 0); + // refresh + if (!noRefresh) this.refresh(); + }, + + skip: function (offset, callBack) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + this.offset = parseInt(offset); + if (this.offset > this.total) this.offset = this.total - this.limit; + if (this.offset < 0 || !w2utils.isInt(this.offset)) this.offset = 0; + this.clear(true); + this.reload(callBack); + } else { + console.log('ERROR: grid.skip() can only be called when you have remote data source.'); + } + }, + + load: function (url, callBack) { + if (url == null) { + console.log('ERROR: You need to provide url argument when calling .load() method of "'+ this.name +'" object.'); + return; + } + // default action + this.clear(true); + this.request('get', {}, url, callBack); + }, + + reload: function (callBack) { + var grid = this; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + grid.selectionSave(); + if (url) { + // need to remember selection (not just last.selection object) + this.load(url, function () { + grid.selectionRestore(); + if (typeof callBack == 'function') callBack(); + }); + } else { + this.reset(true); + this.localSearch(); + this.selectionRestore(); + if (typeof callBack == 'function') callBack({ status: 'success' }); + } + }, + + request: function (cmd, add_params, url, callBack) { + if (add_params == null) add_params = {}; + if (url == '' || url == null) url = this.url; + if (url == '' || url == null) return; + // build parameters list + var params = {}; + if (!w2utils.isInt(this.offset)) this.offset = 0; + if (!w2utils.isInt(this.last.xhr_offset)) this.last.xhr_offset = 0; + // add list params + params['cmd'] = cmd; + params['selected'] = this.getSelection(); + params['limit'] = this.limit; + params['offset'] = parseInt(this.offset) + parseInt(this.last.xhr_offset); + params['search'] = this.searchData; + params['searchLogic'] = this.last.logic; + params['sort'] = this.sortData; + if (this.searchData.length === 0) { + delete params['search']; + delete params['searchLogic']; + } + if (this.sortData.length === 0) { + delete params['sort']; + } + // append other params + $.extend(params, this.postData); + $.extend(params, add_params); + // event before + if (cmd == 'get') { + var edata = this.trigger({ phase: 'before', type: 'request', target: this.name, url: url, postData: params, httpHeaders: this.httpHeaders }); + if (edata.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } + } else { + var edata = { url: url, postData: params, httpHeaders: this.httpHeaders }; + } + // call server to get data + var obj = this; + if (this.last.xhr_offset === 0) { + obj.lock(w2utils.lang(obj.msgRefresh), true); + } else { + var more = $('#grid_'+ this.name +'_rec_more, #grid_'+ this.name +'_frec_more'); + if (this.autoLoad === true) { + more.show().find('td').html('
'); + } else { + more.find('td').html('
'+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
'); + } + } + if (this.last.xhr) try { this.last.xhr.abort(); } catch (e) {} + // URL + url = (typeof edata.url != 'object' ? edata.url : edata.url.get); + if (params.cmd == 'save' && typeof edata.url == 'object') url = edata.url.save; + if (params.cmd == 'delete' && typeof edata.url == 'object') url = edata.url.remove; + // process url with routeData + if (!$.isEmptyObject(obj.routeData)) { + var info = w2utils.parseRoute(url); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + if (obj.routeData[info.keys[k].name] == null) continue; + url = url.replace((new RegExp(':'+ info.keys[k].name, 'g')), obj.routeData[info.keys[k].name]); + } + } + } + // ajax ptions + var ajaxOptions = { + type : 'POST', + url : url, + data : edata.postData, + headers : edata.httpHeaders, + dataType : 'text' // expected data type from server + }; + if (w2utils.settings.dataType == 'HTTP') { + ajaxOptions.data = (typeof ajaxOptions.data == 'object' ? String($.param(ajaxOptions.data, false)).replace(/%5B/g, '[').replace(/%5D/g, ']') : ajaxOptions.data); + } + if (w2utils.settings.dataType == 'HTTPJSON') { + ajaxOptions.data = { request: JSON.stringify(ajaxOptions.data) }; + } + if (w2utils.settings.dataType == 'RESTFULL') { + ajaxOptions.type = 'GET'; + if (params.cmd == 'save') ajaxOptions.type = 'PUT'; // so far it is always update + if (params.cmd == 'delete') ajaxOptions.type = 'DELETE'; + ajaxOptions.data = (typeof ajaxOptions.data == 'object' ? String($.param(ajaxOptions.data, false)).replace(/%5B/g, '[').replace(/%5D/g, ']') : ajaxOptions.data); + } + if (w2utils.settings.dataType == 'RESTFULLJSON') { + ajaxOptions.type = 'GET'; + if (params.cmd == 'save') ajaxOptions.type = 'PUT'; // so far it is always update + if (params.cmd == 'delete') ajaxOptions.type = 'DELETE'; + ajaxOptions.data = JSON.stringify(ajaxOptions.data); + ajaxOptions.contentType = 'application/json'; + } + if (w2utils.settings.dataType == 'JSON') { + ajaxOptions.type = 'POST'; + ajaxOptions.data = JSON.stringify(ajaxOptions.data); + ajaxOptions.contentType = 'application/json'; + } + if (this.method) ajaxOptions.type = this.method; + + this.last.xhr_cmd = params.cmd; + this.last.xhr_start = (new Date()).getTime(); + this.last.xhr = $.ajax(ajaxOptions) + .done(function (data, status, xhr) { + obj.requestComplete(status, cmd, callBack); + }) + .fail(function (xhr, status, error) { + // trigger event + var errorObj = { status: status, error: error, rawResponseText: xhr.responseText }; + var edata2 = obj.trigger({ phase: 'before', type: 'error', error: errorObj, xhr: xhr }); + if (edata2.isCancelled === true) return; + // default behavior + if (status != 'abort') { // it can be aborted by the grid itself + var data; + try { data = $.parseJSON(xhr.responseText); } catch (e) {} + console.log('ERROR: Server communication failed.', + '\n EXPECTED:', { status: 'success', total: 5, records: [{ recid: 1, field: 'value' }] }, + '\n OR:', { status: 'error', message: 'error message' }, + '\n RECEIVED:', typeof data == 'object' ? data : xhr.responseText); + obj.requestComplete('error', cmd, callBack); + } + // event after + obj.trigger($.extend(edata2, { phase: 'after' })); + }); + if (cmd == 'get') { + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + }, + + requestComplete: function(status, cmd, callBack) { + var obj = this; + this.unlock(); + setTimeout(function () { + if (obj.show.statusResponse) obj.status(w2utils.lang('Server Response') + ' ' + ((new Date()).getTime() - obj.last.xhr_start)/1000 +' ' + w2utils.lang('sec')); + }, 10); + this.last.pull_more = false; + this.last.pull_refresh = true; + + // event before + var event_name = 'load'; + if (this.last.xhr_cmd == 'save') event_name = 'save'; + if (this.last.xhr_cmd == 'delete') event_name = 'delete'; + var edata = this.trigger({ phase: 'before', target: this.name, type: event_name, xhr: this.last.xhr, status: status }); + if (edata.isCancelled === true) { + if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); + return; + } + // parse server response + var data; + var responseText = this.last.xhr.responseText; + if (status != 'error') { + // default action + if (responseText != null && responseText != '') { + // check if the onLoad handler has not already parsed the data + if (typeof responseText == "object") { + data = responseText; + } else { + if (typeof obj.parser == 'function') { + data = obj.parser(responseText); + if (typeof data != 'object') { + console.log('ERROR: Your parser did not return proper object'); + } + } else { + // $.parseJSON or $.getJSON did not work because those expect perfect JSON data - where everything is in double quotes + // + // TODO: avoid (potentially malicious) code injection from the response. + try { eval('data = '+ responseText); } catch (e) { } + } + } + if (data == null) { + data = { + status : 'error', + message : w2utils.lang(this.msgNotJSON), + responseText : responseText + }; + } else if (Array.isArray(data)) { + // if it is plain array, assume these are records + data = { + status : 'success', + records : data + } + } + if (obj.recid && data.records) { + // convert recids + for (var i = 0; i < data.records.length; i++) { + data.records[i]['recid'] = data.records[i][obj.recid]; + } + } + if (data['status'] == 'error') { + obj.error(data['message']); + } else { + if (cmd == 'get') { + if (data.total == null) data.total = -1; + if (data.records.length == this.limit) { + this.last.xhr_hasMore = true; + } else { + this.last.xhr_hasMore = false; + this.total = this.last.xhr_offset + data.records.length; + } + if (this.last.xhr_offset === 0) { + this.records = []; + this.summary = []; + if (w2utils.isInt(data.total)) this.total = parseInt(data.total); + } else { + if (data.total != -1 && parseInt(data.total) != parseInt(this.total)) { + this.message(w2utils.lang(this.msgNeedReload), function () { + delete this.last.xhr_offset; + this.reload(); + }.bind(this)); + return; + } + } + // records + if (data.records) { + for (var r = 0; r < data.records.length; r++) { + this.records.push(data.records[r]); + } + } + // summary records (if any) + if (data.summary) { + this.summary = []; + for (var r = 0; r < data.summary.length; r++) { + this.summary.push(data.summary[r]); + } + } + } + if (cmd == 'delete') { + this.reset(); // unselect old selections + this.reload(); + return; + } + } + } + } else { + data = { + status : 'error', + message : w2utils.lang(this.msgAJAXerror), + responseText : responseText + }; + obj.error(w2utils.lang(this.msgAJAXerror)); + } + // event after + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.localSort(); + this.localSearch(); + } + this.total = parseInt(this.total); + // do not refresh if loading on infinite scroll + if (this.last.xhr_offset === 0) { + this.refresh(); + } else { + this.scroll(); + this.resize(); + } + // call back + if (typeof callBack == 'function') callBack(data); // need to be befor event:after + // after event + this.trigger($.extend(edata, { phase: 'after' })); + }, + + error: function (msg) { + var obj = this; + // let the management of the error outside of the grid + var edata = this.trigger({ target: this.name, type: 'error', message: msg , xhr: this.last.xhr }); + if (edata.isCancelled === true) { + if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); + return; + } + this.message(msg); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + getChanges: function () { + var changes = []; + for (var r = 0; r < this.records.length; r++) { + var rec = this.records[r]; + if (rec.w2ui && rec.w2ui.changes != null) { + changes.push($.extend(true, { recid: rec.recid }, rec.w2ui.changes)); + } + } + return changes; + }, + + mergeChanges: function () { + var changes = this.getChanges(); + for (var c = 0; c < changes.length; c++) { + var record = this.get(changes[c].recid); + for (var s in changes[c]) { + if (s == 'recid') continue; // do not allow to change recid + if (typeof changes[c][s] === "object") changes[c][s] = changes[c][s].text; + try { + if (s.indexOf('.') != -1) { + eval("record['" + s.replace(/\./g, "']['") + "'] = changes[c][s]") + } else { + record[s] = changes[c][s]; + } + } catch (e) { + console.log('ERROR: Cannot merge. ', e.message || '', e); + } + if (record.w2ui) delete record.w2ui.changes; + } + } + this.refresh(); + }, + + // =================================================== + // -- Action Handlers + + save: function () { + var obj = this; + var changes = this.getChanges(); + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'save', changes: changes }); + if (edata.isCancelled === true) return; + var url = (typeof this.url != 'object' ? this.url : this.url.save); + if (url) { + this.request('save', { 'changes' : edata.changes }, null, + function (data) { + if (data.status !== 'error') { + // only merge changes, if save was successful + obj.mergeChanges(); + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + ); + } else { + this.mergeChanges(); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + }, + + editField: function (recid, column, value, event) { + var obj = this; + var index = obj.get(recid, true); + var edit = obj.getCellEditable(index, column); + if (!edit) return; + var rec = obj.records[index]; + var col = obj.columns[column]; + var prefix = (col.frozen === true ? '_f' : '_'); + if (['enum', 'file'].indexOf(edit.type) != -1) { + console.log('ERROR: input types "enum" and "file" are not supported in inline editing.'); + return; + } + // event before + var edata = obj.trigger({ phase: 'before', type: 'editField', target: obj.name, recid: recid, column: column, value: value, + index: index, originalEvent: event }); + if (edata.isCancelled === true) return; + value = edata.value; + // default behaviour + this.selectNone(); + this.select({ recid: recid, column: column }); + this.last.edit_col = column; + if (['checkbox', 'check'].indexOf(edit.type) != -1) return; + // create input element + var tr = $('#grid_'+ obj.name + prefix +'rec_' + w2utils.escapeId(recid)); + var el = tr.find('[col='+ column +'] > div'); + // clear previous if any + $(this.box).find('div.w2ui-edit-box').remove(); + // for spreadsheet - insert into selection + if (this.selectType != 'row') { + $('#grid_'+ this.name + prefix + 'selection') + .attr('id', 'grid_'+ this.name + '_editable') + .removeClass('w2ui-selection') + .addClass('w2ui-edit-box') + .prepend('
') + .find('.w2ui-selection-resizer') + .remove(); + el = $('#grid_'+ this.name + '_editable >div:first-child'); + } + if (edit.inTag == null) edit.inTag = ''; + if (edit.outTag == null) edit.outTag = ''; + if (edit.style == null) edit.style = ''; + if (edit.items == null) edit.items = []; + var val = (rec.w2ui && rec.w2ui.changes && rec.w2ui.changes[col.field] != null ? w2utils.stripTags(rec.w2ui.changes[col.field]) : w2utils.stripTags(rec[col.field])); + if (val == null) val = ''; + var old_value = (typeof val != 'object' ? val : ''); + if (edata.old_value != null) old_value = edata.old_value; + if (value != null) val = value; + var addStyle = (col.style != null ? col.style + ';' : ''); + if (typeof col.render == 'string' && ['number', 'int', 'float', 'money', 'percent', 'size'].indexOf(col.render.split(':')[0]) != -1) { + addStyle += 'text-align: right;'; + } + // normalize items + if (edit.items.length > 0 && !$.isPlainObject(edit.items[0])) { + edit.items = w2obj.field.prototype.normMenu(edit.items); + } + switch (edit.type) { + + case 'select': + var html = ''; + for (var i = 0; i < edit.items.length; i++) { + html += ''; + } + el.addClass('w2ui-editable') + .html('' + edit.outTag); + setTimeout(function () { + el.find('select') + .on('change', function (event) { + delete obj.last.move; + }) + .on('blur', function (event) { + if ($(this).data('keep-open') == true) return; + obj.editChange.call(obj, this, index, column, event); + }); + }, 10); + break; + + case 'div': + var $tmp = tr.find('[col='+ column +'] > div'); + var font = 'font-family: '+ $tmp.css('font-family') + '; font-size: '+ $tmp.css('font-size') + ';'; + el.addClass('w2ui-editable') + .html('
' + edit.outTag); + if (value == null) el.find('div.w2ui-input').text(typeof val != 'object' ? val : ''); + // add blur listener + var input = el.find('div.w2ui-input').get(0); + setTimeout(function () { + var tmp = input; + $(tmp).on('blur', function (event) { + if ($(this).data('keep-open') == true) return; + obj.editChange.call(obj, tmp, index, column, event); + }); + }, 10); + if (value != null) $(input).text(typeof val != 'object' ? val : ''); + break; + + default: + var $tmp = tr.find('[col='+ column +'] > div'); + var font = 'font-family: '+ $tmp.css('font-family') + '; font-size: '+ $tmp.css('font-size'); + el.addClass('w2ui-editable') + .html('' + edit.outTag); + // issue #499 + if (edit.type == 'number') { + val = w2utils.formatNumber(val); + } + if (edit.type == 'date') { + val = w2utils.formatDate(w2utils.isDate(val, edit.format, true), edit.format); + } + if (value == null) el.find('input').val(typeof val != 'object' ? val : ''); + // init w2field + var input = el.find('input').get(0); + $(input).w2field(edit.type, $.extend(edit, { selected: val })); + // add blur listener + setTimeout(function () { + var tmp = input; + if (edit.type == 'list') { + tmp = $($(input).data('w2field').helpers.focus).find('input'); + if (typeof val != 'object' && val != '') tmp.val(val).css({ opacity: 1 }).prev().css({ opacity: 1 }); + el.find('input').on('change', function (event) { + obj.editChange.call(obj, input, index, column, event); + }); + } + $(tmp).on('blur', function (event) { + if ($(this).data('keep-open') == true) return; + obj.editChange.call(obj, input, index, column, event); + }); + }, 10); + if (value != null) $(input).val(typeof val != 'object' ? val : ''); + } + + setTimeout(function () { + el.find('input, select, div.w2ui-input') + .data('old_value', old_value) + .on('mousedown', function (event) { + event.stopPropagation(); + }) + .on('click', function (event) { + if (edit.type == 'div') { + expand.call(el.find('div.w2ui-input')[0], null); + } else { + expand.call(el.find('input, select')[0], null); + } + }) + .on('paste', function (event) { + // clean paste to be plain text + var e = event.originalEvent; + event.preventDefault(); + var text = e.clipboardData.getData("text/plain"); + document.execCommand("insertHTML", false, text); + }) + .on('keydown', function (event) { + var el = this; + var val = (el.tagName.toUpperCase() == 'DIV' ? $(el).text() : $(el).val()); + switch (event.keyCode) { + case 8: // backspace; + if (edit.type == 'list' && !$(input).data('w2field')) { // cancel backspace when deleting element + event.preventDefault(); + } + break; + case 9: + case 13: + event.preventDefault(); + break; + case 37: + if (w2utils.getCursorPosition(el) === 0) { + event.preventDefault(); + } + break; + case 39: + if (w2utils.getCursorPosition(el) == val.length) { + w2utils.setCursorPosition(el, val.length); + event.preventDefault(); + } + break; + } + // need timeout so, this handler is executed last + setTimeout(function () { + switch (event.keyCode) { + case 9: // tab + var next_rec = recid; + var next_col = event.shiftKey ? obj.prevCell(index, column, true) : obj.nextCell(index, column, true); + // next or prev row + if (next_col == null) { + var tmp = event.shiftKey ? obj.prevRow(index, column) : obj.nextRow(index, column); + if (tmp != null && tmp != index) { + next_rec = obj.records[tmp].recid; + // find first editable row + for (var c = 0; c < obj.columns.length; c++) { + var edit = obj.getCellEditable(index, c); + if (edit != null && ['checkbox', 'check'].indexOf(edit.type) == -1) { + next_col = parseInt(c); + if (!event.shiftKey) break; + } + } + } + + } + if (next_rec === false) next_rec = recid; + if (next_col == null) next_col = column; + // init new or same record + el.blur(); + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: next_rec, column: next_col }); + } else { + obj.editField(next_rec, next_col, null, event); + } + }, 1); + if (event.preventDefault) event.preventDefault(); + break; + + case 13: // enter + el.blur(); + var next = event.shiftKey ? obj.prevRow(index, column) : obj.nextRow(index, column); + if (next != null && next != index) { + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: obj.records[next].recid, column: column }); + } else { + obj.editField(obj.records[next].recid, column, null, event); + } + }, 1); + } + if (el.tagName.toUpperCase() == 'DIV') { + event.preventDefault(); + } + break; + + case 27: // escape + var old = obj.parseField(rec, col.field); + if (rec.w2ui && rec.w2ui.changes && rec.w2ui.changes[col.field] != null) old = rec.w2ui.changes[col.field]; + if ($(el).data('old_value') != null) old = $(el).data('old_value'); + if (el.tagName.toUpperCase() == 'DIV') { + $(el).text(old != null ? old : ''); + } else { + el.value = old != null ? old : ''; + } + el.blur(); + setTimeout(function () { obj.select({ recid: recid, column: column }); }, 1); + break; + } + // if input too small - expand + expand.call(el, event); + }, 1); + }) + .on('keyup', function (event) { + expand.call(this, event); + }); + // focus and select + setTimeout(function () { + var tmp = el.find('.w2ui-input'); + var len = $(tmp).val().length; + if (edit.type == 'div') len = $(tmp).text().length; + if (tmp.length > 0) { + tmp.focus(); + clearTimeout(obj.last.kbd_timer); // keep focus + if (tmp[0].tagName != 'SELECT') w2utils.setCursorPosition(tmp[0], len); + tmp[0].resize = expand; + expand.call(tmp[0], null); + } + }, 50); + // event after + obj.trigger($.extend(edata, { phase: 'after', input: el.find('input, select, div.w2ui-input') })); + }, 5); // needs to be 5-10 + return; + + function expand(event) { + try { + var val = (this.tagName.toUpperCase() == 'DIV' ? $(this).text() : this.value); + var $sel = $('#grid_'+ obj.name + '_editable'); + var style = 'font-family: '+ $(this).css('font-family') + '; font-size: '+ $(this).css('font-size') + '; white-space: pre;'; + var width = w2utils.getStrWidth(val, style); + if (width + 20 > $sel.width()) { + $sel.width(width + 20); + } + } catch (e) { + } + } + }, + + editChange: function (el, index, column, event) { + var obj = this; + // keep focus + setTimeout(function () { + var $input = $(obj.box).find('#grid_'+ obj.name + '_focus'); + if (!$input.is(':focus')) $input.focus(); + }, 10); + // all other fields + var summary = index < 0; + index = index < 0 ? -index - 1 : index; + var records = summary ? this.summary : this.records; + var rec = records[index]; + var col = this.columns[column]; + var tr = $('#grid_'+ this.name + (col.frozen === true ? '_frec_' : '_rec_') + w2utils.escapeId(rec.recid)); + var new_val = (el.tagName && el.tagName.toUpperCase() == 'DIV' ? $(el).text() : el.value); + var old_val = this.parseField(rec, col.field); + var tmp = $(el).data('w2field'); + if (tmp) { + if (tmp.type == 'list') new_val = $(el).data('selected'); + if ($.isEmptyObject(new_val) || new_val == null) new_val = ''; + if (!$.isPlainObject(new_val)) new_val = tmp.clean(new_val); + } + if (el.type == 'checkbox') { + if (rec.w2ui && rec.w2ui.editable === false) el.checked = !el.checked; + new_val = el.checked; + } + // change/restore event + var edata = { + phase: 'before', type: 'change', target: this.name, input_id: el.id, recid: rec.recid, index: index, column: column, + originalEvent: (event.originalEvent ? event.originalEvent : event), + value_new: new_val, + value_previous: (rec.w2ui && rec.w2ui.changes && rec.w2ui.changes.hasOwnProperty(col.field) ? rec.w2ui.changes[col.field]: old_val), + value_original: old_val + }; + if ($(event.target).data('old_value') != null) edata.value_previous = $(event.target).data('old_value'); + // if (old_val == null) old_val = ''; -- do not uncomment, error otherwise + while (true) { + new_val = edata.value_new; + if ((typeof new_val != 'object' && String(old_val) != String(new_val)) || + (typeof new_val == 'object' && new_val.id != old_val && (typeof old_val != 'object' || old_val == null || new_val.id != old_val.id))) { + // change event + edata = this.trigger($.extend(edata, { type: 'change', phase: 'before' })); + if (edata.isCancelled !== true) { + if (new_val !== edata.value_new) { + // re-evaluate the type of change to be made + continue; + } + // default action + rec.w2ui = rec.w2ui || {}; + rec.w2ui.changes = rec.w2ui.changes || {}; + rec.w2ui.changes[col.field] = edata.value_new; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + } else { + // restore event + edata = this.trigger($.extend(edata, { type: 'restore', phase: 'before' })); + if (edata.isCancelled !== true) { + if (new_val !== edata.value_new) { + // re-evaluate the type of change to be made + continue; + } + // default action + if (rec.w2ui && rec.w2ui.changes) delete rec.w2ui.changes[col.field]; + if (rec.w2ui && $.isEmptyObject(rec.w2ui.changes)) delete rec.w2ui.changes; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + } + break; + } + // refresh cell + var cell = $(tr).find('[col='+ column +']'); + if (!summary) { + if (rec.w2ui && rec.w2ui.changes && rec.w2ui.changes[col.field] != null) { + cell.addClass('w2ui-changed'); + } else { + cell.removeClass('w2ui-changed'); + } + // update cell data + cell.replaceWith(this.getCellHTML(index, column, summary)); + } + // remove + $(this.box).find('div.w2ui-edit-box').remove(); + // 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'); + } + }, + + "delete": function (force) { + var time = (new Date()).getTime(); + var obj = this; + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'delete', force: force }); + if (edata.isCancelled === true) return; + force = edata.force; + // hide all tooltips + setTimeout(function () { $().w2tag(); }, 20); + // default action + var recs = this.getSelection(); + if (recs.length === 0) return; + if (this.msgDelete != '' && !force) { + this.message({ + width : 350, + height : 170, + body : '
' + w2utils.lang(obj.msgDelete) + '
', + buttons : ''+ + '', + 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:last-child').focus(); + clearTimeout(obj.last.kbd_timer); + }, 25); + } + }); + return; + } + this.message(); // hides confirmation message + // 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') { + 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.apply(this, 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.apply(this, sel); + if (flag === true && sel.length == 1) { + this.unselect({ recid: recid, column: column }); + } else { + this.select({ recid: recid, column: column }); + } + } else { + if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) 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 { + // 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.apply(this, 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).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).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 + if (this.show.toolbarDelete || this.onDelete) 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_col) columns = [this.last.edit_col]; + 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.apply(obj, 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.apply(obj, 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.apply(obj, 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.apply(obj, 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.apply(obj, tmp); + } else { + var tmp = []; + for (var c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); + obj.select.apply(obj, tmp); + } + } + } else { // move selected record + if (sel.length > 300) this.selectNone(); else this.unselect.apply(this, 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.apply(obj, tmp); + } else { + var tmp = []; + for (var c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); + obj.select.apply(obj, tmp); + } + } + } else { // move selected record + if (sel.length > 300) this.selectNone(); else this.unselect.apply(this, 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); + } + // clear + setTimeout(function () { obj["delete"](true); }, 100); + } + 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.apply(obj, 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.apply(obj, 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') { + 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, parseInt(event.index), event.originalEvent); + } + } + ); + } + // cancel event + if (event.preventDefault) event.preventDefault(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, + + menuClick: function (recid, index, event) { + var obj = this; + // event before + var edata = obj.trigger({ phase: 'before', type: 'menuClick', target: obj.name, originalEvent: event, + recid: recid, menuIndex: index, menuItem: obj.menu[index] }); + 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 { + switch (String(this.sortData[sortIndex].direction)) { + 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' })); + this.refresh(); + } else { + // event after + this.trigger($.extend(edata, { phase: 'after' })); + 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 += w2utils.stripTags(this.getCellHTML(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.caption ? col.caption : col.field); + if (col.caption && col.caption.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 += '"' + w2utils.stripTags(this.getCellHTML(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, 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, originalEvent: oEvent }); + if (edata.isCancelled === true) return ''; + text = edata.text; + return edata; + } + }, + + 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; + var field = this.columns[col + cnt].field; + rec.w2ui = rec.w2ui || {}; + rec.w2ui.changes = rec.w2ui.changes || {}; + rec.w2ui.changes[field] = 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.apply(this, newSel); + this.refresh(); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + // ================================================== + // --- 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 isSummary = (this.records[index] && this.records[index].recid == recid ? false : true); + var col_ind = this.getColumn(field, true); + var rec = (isSummary ? this.summary[index] : this.records[index]); + var col = this.columns[col_ind]; + var cell = $(this.box).find('#grid_'+ this.name + '_data_'+ index +'_'+ col_ind); + if (rec == null) return false; + // set cell html and changed flag + cell.replaceWith(this.getCellHTML(index, col_ind, isSummary)); + cell = $(this.box).find('#grid_'+ this.name + '_data_'+ index +'_'+ col_ind); // need to recelect as it was replaced + if (rec.w2ui && rec.w2ui.changes && rec.w2ui.changes[col.field] != null) { + cell.addClass('w2ui-changed'); + } else { + cell.removeClass('w2ui-changed'); + } + // assign style + if (rec.w2ui && rec.w2ui.style != null && !$.isEmptyObject(rec.w2ui.style)) { + if (typeof rec.w2ui.style == 'string') { + $(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(rec.recid)).attr('style', rec.w2ui.style); + } + if ($.isPlainObject(rec.w2ui.style) && typeof rec.w2ui.style[col_ind] == 'string') { + cell.attr('style', rec.w2ui.style[col_ind]); + } + } else { + cell.attr('style', ''); + } + // assign class + if (rec.w2ui && rec.w2ui.class != null && !$.isEmptyObject(rec.w2ui.class)) { + if (typeof rec.w2ui.class == 'string') { + $(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(rec.recid)).addClass(rec.w2ui.class); + } + if ($.isPlainObject(rec.w2ui.class) && typeof rec.w2ui.class[col_ind] == 'string') { + cell.addClass(rec.w2ui.class[col_ind]); + } + } + }, + + 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.caption = this.searches[0].caption; + } + for (var s = 0; s < this.searches.length; s++) { + if (this.searches[s].field == this.last.field) this.last.caption = this.searches[s].caption; + } + if (this.last.multi) { + el.attr('placeholder', '[' + w2utils.lang('Multiple Fields') + ']'); + el.w2field('clear'); + } else { + el.attr('placeholder', w2utils.lang(this.last.caption)); + } + 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 && tmp.type != 'list')) { + $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 str = []; + 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; + if (str.indexOf(sdata.value) == -1) str.push(sdata.value); + } + if (str.length > 0) $(obj.box).find('.w2ui-grid-data > div').w2marker(str); + }, 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 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] +'
'+ + '
'; + $('#grid_'+ this.name +'_body').html(bodyHTML); + 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') + .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.caption = ''; + } else { + this.last.field = this.searches[tmp].field; + this.last.caption = this.searches[tmp].caption; + } + } else { + this.last.field = 'all'; + this.last.caption = w2utils.lang('All Fields'); + } + } + // insert elements + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-grid') + .html('
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + ' '+ + ' '+ + '
'); + 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.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 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).on('mousedown', mouseStart); + // 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-'+ this.name) + .on('resize.w2ui-'+ this.name, function (event) { + 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 if (obj.multiSelect || obj.reorderRows) { + 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; + } + $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); + } + if (obj.reorderRows == true) { + var el = event.target; + if (el.tagName.toUpperCase() != 'TD') el = $(el).parents('td')[0]; + if ($(el).hasClass('w2ui-col-number')) { + 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('
'); + $('#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', mouseMove); + $(document).on('mouseup', 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 tmp = $(event.target).parents('tr'); + var recid = tmp.attr('recid'); + if (recid != mv.from) { + var row1 = $('#grid_'+ obj.name + '_rec_'+ mv.recid); + var row2 = $('#grid_'+ obj.name + '_rec_'+ recid); + $(obj.box).find('.tmp-ghost').css('border-top', '0px'); + row2.addClass('tmp-ghost').css('border-top', '2px solid #769EFC'); + // MOVABLE GHOST + // if (event.screenY - mv.lastY < 0) row1.after(row2); else row2.after(row1); + mv.lastY = event.screenY; + mv.to = recid; + } + var ghost = $('#grid_'+ obj.name + '_ghost'); + var recs = $(obj.box).find('.w2ui-grid-records'); + 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.apply(obj, 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.apply(obj, 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.apply(obj, 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(); + obj.refresh(); + return; + } + // default behavior + var ind1 = obj.get(mv.from, true); + var ind2 = obj.get(mv.to, true); + 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(); + obj.refresh(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + } + delete obj.last.move; + $(document).off('mousemove', mouseMove); + $(document).off('mouseup', mouseStop); + } + }, + + destroy: function () { + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'destroy' }); + if (edata.isCancelled === true) return; + // remove events + $(window).off('resize.w2ui-'+ this.name); + // 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') + .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].caption; + 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(){ + if ( !_dragData.pressed ) 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' ); + 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.originalPos = parseInt( $( event.originalEvent.target ).parent( '.w2ui-head' ).attr( 'col' ), 10 ); + //_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; + // 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'); + this.showColumn(col.field); + } else { + $el.addClass('w2ui-icon-empty').removeClass('w2ui-icon-check'); + this.hideColumn(col.field); + } + } + if (!event.shiftKey && !event.metaKey && !event.ctrlKey) { + // timeout needed for visual delay + setTimeout(function () { + $().w2overlay({ name: obj.name + '_toolbar' }); + }, 150); + } + // 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) { + this.toolbar.items.push($.extend(true, {}, this.buttons['add'])); + } + if (this.show.toolbarEdit) { + this.toolbar.items.push($.extend(true, {}, this.buttons['edit'])); + } + if (this.show.toolbarDelete) { + this.toolbar.items.push($.extend(true, {}, this.buttons['delete'])); + } + if (this.show.toolbarSave) { + 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 tb = this; + var it = this.get(id); + if (it.checked) { + obj.searchClose(); + setTimeout(function () { tb.uncheck(id); }, 1); + } else { + obj.searchOpen(); + event.originalEvent.stopPropagation(); + function tmp_close() { + if ($('#w2ui-overlay-'+ obj.name + '-searchOverlay').data('keepOpen') === true) return; + tb.uncheck(id); + $(document).off('click', 'body', tmp_close); + } + $(document).on('click', 'body', tmp_close); + } + break; + case 'w2ui-add': + // events + var edata = obj.trigger({ phase: 'before', target: obj.name, type: 'add', recid: null }); + obj.trigger($.extend(edata, { 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 edata = obj.trigger({ phase: 'before', target: obj.name, type: 'edit', recid: recid }); + obj.trigger($.extend(edata, { 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' })); + }); + } + }, + + initResize: function () { + var obj = this; + //if (obj.resizing === true) return; + $(this.box).find('.w2ui-resizer') + .off('click') + .on('click', function (event) { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (event.preventDefault) event.preventDefault(); + }) + .off('mousedown') + .on('mousedown', 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')) + }; + 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 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); + obj.columns[obj.last.tmp.col].size = (parseInt(obj.columns[obj.last.tmp.col].size) + obj.last.tmp.x) + 'px'; + obj.resizeRecords(); + obj.scroll(); + // reset + obj.last.tmp.x = event.screenX; + obj.last.tmp.y = event.screenY; + }; + var mouseUp = function (event) { + delete obj.resizing; + $(document).off('mousemove', 'body'); + $(document).off('mouseup', 'body'); + obj.resizeRecords(); + obj.scroll(); + // event before + obj.trigger($.extend(edata, { phase: 'after', originalEvent: event })); + }; + $(document).on('mousemove', 'body', mouseMove); + $(document).on('mouseup', 'body', mouseUp); + }) + .each(function (index, el) { + var td = $(el).parent(); + $(el).css({ + "height" : '25px', + "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 += ''; + 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.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 processiong + 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.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'; + + var operator = + ''; + + html += ''+ + ' ' + + ' ' + + ' '+ + ' ' + + ''; + } + html += ''+ + ' '+ + '
'+ btn +''+ (s.caption || '') +''+ 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(); + // fld1.w2field(search.type); + switch ($(el).val()) { +// case 'in': +// case 'not in': +// fld1.w2field('clear'); +// break; + 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 = 'begins'; // default operator for text + // 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.caption != null) txt = si.caption; + 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 + if (obj.columnGroups[obj.columnGroups.length-1].caption != '') obj.columnGroups.push({ caption: '' }); + + if (obj.show.lineNumbers) { + html1 += ''+ + '
 
'+ + ''; + } + if (obj.show.selectColumn) { + html1 += ''+ + '
 
'+ + ''; + } + if (obj.show.expandColumn) { + html1 += ''+ + '
 
'+ + ''; + } + var ii = 0; + html2 += ''; + for (var i=0; i'; + } + tmpf = ''+ + resizer + + '
'+ + '
'+ + (!col.caption ? ' ' : col.caption) + + '
'+ + ''; + if (col && col.frozen) html1 += tmpf; else html2 += tmpf; + } else { + tmpf = ''+ + '
'+ + (!colg.caption ? ' ' : colg.caption) + + '
'+ + ''; + 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 += ''; + for (var i = 0; i < obj.columns.length; i++) { + var col = obj.columns[i]; + 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 (new RegExp('asc', 'i').test(this.sortData[si].direction)) sortStyle = 'w2ui-sort-up'; + if (new RegExp('desc', 'i').test(this.sortData[si].direction)) 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 html = ''+ + (col.resizable !== false ? '
' : '') + + '
'+ + '
'+ + (!col.caption ? ' ' : col.caption) + + '
'+ + ''; + + 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 }); + } + }, 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() / 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]; + } + 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'); + 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 (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; + // need this to enable scrolling when this.limit < then a screen can fit + if (records.height() < buffered * this.recordHeight && records.css('overflow-y') == 'hidden') { + // TODO: is this needed? + // if (this.total > 0) this.refresh(); + return; + } + // 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) * obj.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'); + } else { + var more = $('#grid_'+ this.name +'_rec_more, #grid_'+ this.name +'_frec_more'); + if (more.css('display') == 'none') { + more.show() + .on('click', function () { + obj.last.pull_more = true; + obj.last.xhr_offset += obj.limit; + obj.request('get'); + // show spinner the last + $(this).find('td').html('
'); + }); + } + if (more.find('td .w2ui-spinner').length > 0 || more.find('td').text().indexOf('Load') == -1) { + more.find('td').html('
'+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
'); + } + } + } + // check for grid end + if (buffered >= this.total - this.offset && this.total != -1) $('#grid_'+ this.name +'_rec_more, #grid_'+ this.name +'_frec_more').hide(); + + function markSearch() { + // mark search + if (!obj.markSearch) return; + clearTimeout(obj.last.marker_timer); + obj.last.marker_timer = setTimeout(function () { + // mark all search strings + var str = []; + 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; + if (str.indexOf(sdata.value) == -1) str.push(sdata.value); + } + if (str.length > 0) $(obj.box).find('.w2ui-grid-data > div').w2marker(str); + }, 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 += ''; + 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 && record[this.recid] != null) record.recid = record[this.recid]; + 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) { + rec_html1 += + ''+ + (summary !== 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 += ''; + 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 col = this.columns[col_ind]; + if (col == null) return ''; + var record = (summary !== true ? this.records[ind] : this.summary[ind]); + var data = this.getCellValue(ind, col_ind, summary); + var edit = this.getCellEditable(ind, col_ind); + var style = 'max-height: '+ parseInt(this.recordHeight) +'px;'; + 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) { + if (!col.info.icon) col.info.icon = 'w2ui-icon-info'; + infoBubble += ''; + } + // various renderers + if (col.render != null) { + if (typeof col.render == 'function') { + data = $.trim(col.render.call(this, record, ind, col_ind, data)); + if (data.length < 4 || data.substr(0, 4).toLowerCase() != '' + infoBubble + String(data) + ''; + } + } + if (typeof col.render == 'object') { + data = '
' + infoBubble + (col.render[data] || '') + '
'; + } + 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]]; + data = '
' + infoBubble + (typeof func == 'function' ? func(data, tmp[1]) : '') + '
'; + } + } else { + // if editable checkbox + if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { + var changeInd = summary ? -(ind + 1) : ind; + style += 'text-align: center;'; + data = ''; + infoBubble = ''; + } + if (this.show.recordTitles) { + // title overwrite + var title = w2utils.stripTags(String(data).replace(/"/g, "''")); + if (col.title != null) { + if (typeof col.title == 'function') title = col.title.call(this, record, ind, col_ind); + if (typeof col.title == 'string') title = col.title; + } + } + 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; + // data + data = ' 1 ? 'colspan="'+ col_span + '"' : '') + + '>' + data + ''; + + return data; + }, + + 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); + } 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.caption + '' + ((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); + } 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) { + 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, + caption : this.last.caption, + field : this.last.field, + scrollTop : this.last.scrollTop, + scrollLeft : this.last.scrollLeft + }, + sortData : [], + searchData : [] + }; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + state.columns.push({ + field : col.field, + hidden : col.hidden ? true : false, + frozen : col.frozen ? true : false, + size : col.size ? col.size : null, + sizeCalculated : col.sizeCalculated ? col.sizeCalculated : null, + sizeOriginal : col.sizeOriginal ? col.sizeOriginal : null, + sizeType : col.sizeType ? col.sizeType : null + }); + } + 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) { + 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; + }, + + 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; + 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 +* +* == 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 })); + } + if ($(this).length > 0) { + object.render($(this)[0]); + } + w2ui[object.name] = object; + 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 + }, + onRefresh : null, + onShow : null, + onHide : null + }, + + // alias for content + html: function (panel, data, transition) { + return this.content(panel, data, transition); + }, + + content: function (panel, data, transition) { + var obj = this; + var p = this.get(panel); + // if it is CSS panel + if (panel == 'css') { + $('#layout_'+ obj.name +'_panel_css').html(''); + return true; + } + if (p == null) return false; + if (data == null) { + return p.content; + } + // event before + var edata = this.trigger({ phase: 'before', type: 'content', target: panel, object: p, content: data, transition: transition }); + if (edata.isCancelled === true) return; + + if (data instanceof jQuery) { + console.log('ERROR: You can not pass jQuery object to w2layout.content() method'); + return false; + } + 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); + // 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 true; + }, + + 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.content(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.content(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(); + } + this.showToolbar(panel); + this.refresh('main'); + } 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) { + w2ui[obj.name].resize(); + }, + resizeStart : resizeStart, + mouseMove : resizeMove, + mouseUp : resizeStop + }; + $(window).on('resize', 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 && 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 +* +* == 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 (parseInt($(this).css('height')) !== 0) dlgOptions['height'] = parseInt($(this).css('height')); + } + // 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 + }, + 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; + 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; + } + 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; + 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; + + // 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('opacity', '1') + .css(w2utils.cssPrefix({ + 'transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', + 'transform' : 'scale(1)' + })); + obj.focus(); + }, 1); + // clean transform + setTimeout(function () { + $('#w2ui-popup').css(w2utils.cssPrefix('transform', '')); + // event after + w2popup.status = 'open'; + setTimeout(function () { + obj.trigger($.extend(edata, { phase: 'after' })); + }, 100); + }, options.speed * 1000); + + } 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 onChange + 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); + }); + + // 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; + $('#w2ui-popup').css(w2utils.cssPrefix({ + 'transition': 'none', + 'transform' : 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)' + })); + } + + 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(); + } + return this; + }, + + 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('opacity', '0') + .css(w2utils.cssPrefix({ + 'transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', + 'transform' : 'scale(0.9)' + })); + w2popup.unlockScreen(options); + setTimeout(function () { + // return template + obj.restoreTemplate(); + $('#w2ui-popup').remove(); + w2popup.status = 'closed'; + // restore active + if (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; + // remove message + if ($.trim(options.html) === '' && $.trim(options.body) === '' && $.trim(options.buttons) === '') { + var $msg = $('#w2ui-popup #w2ui-message'+ (msgCount-1)); + var options = $msg.data('options') || {}; + $msg.css(w2utils.cssPrefix({ + 'transition': '0.15s', + 'transform': 'translateY(-' + options.height + 'px)' + })); + if (msgCount == 1) { + w2popup.unlock(150); + } else { + $('#w2ui-popup #w2ui-message'+ (msgCount-2)).css('z-index', 1500); + } + setTimeout(function () { + var $focus = $msg.data('prev_focus'); + $msg.remove(); + if ($focus && $focus.length > 0) { + $focus.focus(); + } else { + obj.focus(); + } + if (typeof options.onClose == 'function') options.onClose(); + }, 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); + head.css('z-index', 1501); + // add message + $('#w2ui-popup .w2ui-box') + .before(''); + $('#w2ui-popup #w2ui-message'+ msgCount).data('options', options).data('prev_focus', $(':focus')); + 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(w2utils.cssPrefix({ + 'transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)') + })); + }, 1); + // timer for lock + if (msgCount === 0) w2popup.lock(); + 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(); + }, 350); + } + } + }, + + focus: function () { + var tmp = null; + var pop = $('#w2ui-popup'); + var sel = 'input:visible, button:visible, select:visible, textarea:visible'; + // 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'); + 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, + 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 : '' + + '', + onOpen: function () { + $('#w2ui-popup .w2ui-message .w2ui-btn').on('click.w2confirm', function (event) { + w2popup._confirm_btn = event.target.id; + w2popup.message(); + }); + }, + onClose: function () { + // 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); + } + // 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 : ''+ + '', + 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(); + }); + $('#w2ui-popup .w2ui-popup-btn#Yes').focus(); + }, 1); + }, + 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 = { + label : '', + value : '', + attrs : '', + title : w2utils.lang('Notification'), + ok_text : w2utils.lang('Ok'), + cancel_text : w2utils.lang('Cancel'), + width : ($('#w2ui-popup').length > 0 ? 400 : 450), + height : ($('#w2ui-popup').length > 0 ? 170 : 220), + callBack : null + } + + 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 : '
'+ + ' '+ + ' '+ + '
', + buttons : '', + onOpen: function () { + $('#w2prompt').val(options.value); + $('#w2ui-popup .w2ui-message .w2ui-btn#Ok').on('click.w2prompt', function (event) { + w2popup._prompt_value = $('#w2prompt').val(); + w2popup.message(); + }); + $('#w2ui-popup .w2ui-message .w2ui-btn#Cancel').on('click.w2prompt', function (event) { + w2popup._prompt_value = null; + w2popup.message(); + }); + // set focus + setTimeout(function () { $('#w2prompt').focus(); }, 100); + }, + 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 () { + if (typeof options.callBack == 'function' && w2popup._prompt_value != null) { + options.callBack(w2popup._prompt_value); + } + }, 300); + } + // 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 : '
', + buttons : '', + 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._prompt_value = $('#w2prompt').val(); + w2popup.close(); + if (typeof options.callBack == 'function') options.callBack(w2popup._prompt_value); + }); + $('#w2ui-popup .w2ui-popup-btn#Cancel').on('click', function (event) { + w2popup._prompt_value = null; + w2popup.close(); + }); + $('#w2ui-popup .w2ui-popup-btn#Ok'); + // set focus + setTimeout(function () { $('#w2prompt').focus(); }, 100); + }, 1); + }, + 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 + w2popup.close(); + break; + case 27: // esc + w2popup.close(); + break; + } + } + } + }); + } + return { + change: function (fun) { + $('#w2prompt').on('keyup', fun).keyup(); + return this; + }, + ok: function (fun) { + options.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 ?? +* +************************************************************************/ + +(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.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.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]); + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + 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); + this.tabs = this.tabs.slice(0, middle).concat([newTab], this.tabs.slice(middle)); + } + this.refresh(tab[i].id); + this.resize(); + } + }, + + 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
'; + } + var tabHTML = closable + + '
' + w2utils.lang(text) + '
'; + if (jq_el.length === 0) { + // does not exist - create it + var addStyle = ''; + if (tab.hidden) { addStyle += 'display: none;'; } + if (tab.disabled) { addStyle += 'opacity: 0.2;'; } + var html = ''+ tabHTML + ''; + if (this.get(id, true) !== this.tabs.length-1 && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).length > 0) { + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).before(html); + } else { + $(this.box).find('#tabs_'+ this.name +'_right').before(html); + } + } else { + // refresh + jq_el.html(tabHTML); + if (tab.hidden) { jq_el.css('display', 'none'); } + else { jq_el.css('display', ''); } + if (tab.disabled) { jq_el.css({ 'opacity': '0.2' }); } + else { jq_el.css({ 'opacity': '1' }); } + } + } + // right html + $('#tabs_'+ this.name +'_right').html(this.right); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + render: function (box) { + var time = (new Date()).getTime(); + // event before + var edata = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (edata.isCancelled === true) return; + // default action + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (box != null) { + if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html(''); + } + this.box = box; + } + if (!this.box) return false; + // render all buttons + var html = '
'+ + ''+ + ' '+ + '
'+ this.right +'
'+ + '
'+ + '
'+ + '
'; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-tabs') + .html(html); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + this.refresh(); + this.resize(); + return (new Date()).getTime() - time; + }, + + scroll: function (direction) { + var box = $(this.box); + var obj = this; + var scrollBox = box.find('.w2ui-scroll-wrapper'); + var scrollLeft = scrollBox.scrollLeft(); + var width1, width2, scroll; + + switch (direction) { + case 'left': + width1 = scrollBox.outerWidth(); + width2 = scrollBox.find(':first').outerWidth(); + scroll = scrollLeft - width1 + 50; // 35 is width of both button + if (scroll <= 0) scroll = 0; + scrollBox.animate({ scrollLeft: scroll }, 300); + break; + + case 'right': + width1 = scrollBox.outerWidth(); + width2 = scrollBox.find(':first').outerWidth(); + scroll = scrollLeft + width1 - 50; // 35 is width of both button + if (scroll >= width2 - width1) scroll = width2 - width1; + scrollBox.animate({ scrollLeft: scroll }, 300); + break; + } + setTimeout(function () { obj.resize(); }, 350); + }, + + + resize: function () { + var time = (new Date()).getTime(); + // event before + var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (edata.isCancelled === true) return; + + // show hide overflow buttons + var box = $(this.box); + box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide(); + var scrollBox = box.find('.w2ui-scroll-wrapper'); + if (scrollBox.find(':first').outerWidth() > scrollBox.outerWidth()) { + // we have overflowed content + if (scrollBox.scrollLeft() > 0) { + box.find('.w2ui-scroll-left').show(); + } + if (scrollBox.scrollLeft() < scrollBox.find(':first').outerWidth() - scrollBox.outerWidth()) { + box.find('.w2ui-scroll-right').show(); + } + } + + // event after + 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; + // clean up + if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + // =================================================== + // -- Internal Event Handlers + + click: function (id, event) { + var tab = this.get(id); + if (tab == null || tab.disabled) return false; + // event before + var edata = this.trigger({ phase: 'before', type: 'click', target: id, tab: tab, object: tab, originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active) +' .w2ui-tab').removeClass('active'); + this.active = tab.id; + // route processing + if (typeof tab.route == 'string') { + var route = tab.route !== '' ? String('/'+ tab.route).replace(/\/{2,}/g, '/') : ''; + var info = w2utils.parseRoute(route); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue; + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); + } + } + setTimeout(function () { window.location.hash = route; }, 1); + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + this.refresh(id); + }, + + animateClose: function(id, event) { + var tab = this.get(id); + if (tab == null || tab.disabled) return false; + // event before + var edata = this.trigger({ phase: 'before', type: 'close', target: id, object: this.get(id), originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + var obj = this; + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).css(w2utils.cssPrefix('transition', '.2s')).css('opacity', '0'); + setTimeout(function () { + var width = $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).width(); + $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)) + .html('
'); + setTimeout(function () { + $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).find(':first-child').css({ 'width': '0px' }); + }, 50); + }, 200); + setTimeout(function () { + obj.remove(id); + }, 450); + // event before + this.trigger($.extend(edata, { phase: 'after' })); + this.refresh(); + }, + + animateInsert: function(id, tab) { + if (this.get(id) == null) return; + if (!$.isPlainObject(tab)) return; + // check for unique + if (!w2utils.checkUniqueId(tab.id, this.tabs, 'tabs', this.name)) return; + // insert simple div + var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); + if (jq_el.length !== 0) return; // already exists + // measure width + if (tab.text == null && tab.caption != null) tab.text = tab.caption; + var tmp = '
'+ + ''+ + '
'+ + (tab.closable ? '
' : '') + + '
'+ tab.text +'
'+ + '
'+ + '
'; + $('body').append(tmp); + // create dummy element + var tabHTML = '
 
'; + var addStyle = ''; + if (tab.hidden) { addStyle += 'display: none;'; } + if (tab.disabled) { addStyle += 'opacity: 0.2;'; } + var html = ''+ tabHTML +''; + if (this.get(id, true) !== this.tabs.length && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).length > 0) { + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).before(html); + } else { + $(this.box).find('#tabs_'+ this.name +'_right').before(html); + } + // -- move + var obj = this; + setTimeout(function () { + var width = $('#_tmp_simple_tab').width(); + $('#_tmp_tabs').remove(); + $('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id) +' > div').css('width', width+'px'); + }, 1); + setTimeout(function () { + // insert for real + obj.insert(id, tab); + }, 200); + } + }; + + $.extend(w2tabs.prototype, w2utils.event); + w2obj.tabs = w2tabs; +})(jQuery); + +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2toolbar - toolbar widget +* - $().w2toolbar - jQuery wrapper +* - Dependencies: jQuery, w2utils, w2field +* +* == NICE TO HAVE == +* - vertical toolbar +* +************************************************************************/ + +(function ($) { + var w2toolbar = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.routeData = {}; // data for dynamic routes + this.items = []; + this.right = ''; // HTML text on the right of toolbar + this.tooltip = 'top|left';// can be top, bottom, left, right + + $.extend(true, this, w2obj.toolbar, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2toolbar = function(method) { + if ($.isPlainObject(method)) { + // check name parameter + if (!w2utils.checkName(method, 'w2toolbar')) return; + // extend items + var items = method.items || []; + var object = new w2toolbar(method); + $.extend(object, { items: [], handlers: [] }); + for (var i = 0; i < items.length; i++) { + object.items[i] = $.extend({}, w2toolbar.prototype.item, items[i]); + // menus + if (object.items[i].type == 'menu-check') { + var item = object.items[i]; + if (!Array.isArray(item.selected)) item.selected = []; + if (Array.isArray(item.items)) { + for (var j = 0; j < item.items.length; j++) { + var it = item.items[j]; + if (it.checked && item.selected.indexOf(it.id) == -1) item.selected.push(it.id); + if (!it.checked && item.selected.indexOf(it.id) != -1) it.checked = true; + if (it.checked == null) it.checked = false; + } + } + } + else if (object.items[i].type == 'menu-radio') { + var item = object.items[i]; + if (Array.isArray(item.items)) { + for (var j = 0; j < item.items.length; j++) { + var it = item.items[j]; + if (it.checked && item.selected == null) item.selected = it.id; else it.checked = false; + if (!it.checked && item.selected == it.id) it.checked = true; + if (it.checked == null) it.checked = false; + } + } + } + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + 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 + + w2toolbar.prototype = { + onClick : null, + onRender : null, + onRefresh : null, + onResize : null, + onDestroy : null, + + item: { + id : null, // command to be sent to all event handlers + type : 'button', // button, check, radio, drop, menu, menu-radio, menu-check, break, html, spacer + text : null, + html : '', + tooltip : null, // w2toolbar.tooltip should be + count : null, + hidden : false, + disabled : false, + checked : false, // used for radio buttons + img : null, + icon : null, + route : null, // if not null, it is route to go + arrow : true, // arrow down for drop/menu types + style : null, // extre css style for caption + color : null, // color value - used in color pickers + transparent : null, // transparent t/f - used in color pickers + group : null, // used for radio buttons + items : null, // for type menu* it is an array of items in the menu + selected : null, // used for menu-check, menu-radio + overlay : {}, + onClick : null, + onRefresh : null + }, + + add: function (items) { + this.insert(null, items); + }, + + insert: function (id, items) { + if (!$.isArray(items)) items = [items]; + for (var o = 0; o < items.length; o++) { + // checks + if (items[o].type == null) { + console.log('ERROR: The parameter "type" is required but not supplied in w2toolbar.add() method.'); + return; + } + if ($.inArray(String(items[o].type), ['button', 'check', 'radio', 'drop', 'menu', 'menu-radio', 'menu-check', 'color', 'text-color', 'break', 'html', 'spacer']) == -1) { + console.log('ERROR: The parameter "type" should be one of the following [button, check, radio, drop, menu, break, html, spacer] '+ + 'in w2toolbar.add() method.'); + return; + } + if (items[o].id == null && items[o].type != 'break' && items[o].type != 'spacer') { + console.log('ERROR: The parameter "id" is required but not supplied in w2toolbar.add() method.'); + return; + } + if (!w2utils.checkUniqueId(items[o].id, this.items, 'toolbar items', this.name)) return; + // add item + var it = $.extend({}, w2toolbar.prototype.item, items[o]); + if (id == null) { + this.items.push(it); + } else { + var middle = this.get(id, true); + this.items = this.items.slice(0, middle).concat([it], this.items.slice(middle)); + } + this.refresh(it.id); + this.resize(); + } + }, + + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it || String(arguments[a]).indexOf(':') != -1) continue; + removed++; + // remove from screen + $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove(); + // remove from array + var ind = this.get(it.id, true); + if (ind != null) this.items.splice(ind, 1); + } + this.resize(); + return removed; + }, + + set: function (id, newOptions) { + var item = this.get(id); + if (item == null) return false; + $.extend(item, newOptions); + this.refresh(String(id).split(':')[0]); + return true; + }, + + get: function (id, returnIndex) { + if (arguments.length === 0) { + var all = []; + for (var i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id != null) all.push(this.items[i1].id); + return all; + } + var tmp = String(id).split(':'); + for (var i2 = 0; i2 < this.items.length; i2++) { + var it = this.items[i2]; + // find a menu item + if (['menu', 'menu-radio', 'menu-check'].indexOf(it.type) != -1 && tmp.length == 2 && it.id == tmp[0]) { + for (var i = 0; i < it.items.length; i++) { + var item = it.items[i]; + if (item.id == tmp[1] || (item.id == null && item.text == tmp[1])) { + if (returnIndex == true) return i; else return item; + } + } + } else if (it.id == tmp[0]) { + if (returnIndex == true) return i2; else return it; + } + } + return null; + }, + + show: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.hidden = false; + tmp.push(String(arguments[a]).split(':')[0]); + } + setTimeout(function () { for (var t=0; t 1) { + var subItem = this.get(id); + if (subItem && !subItem.disabled) { + obj.menuClick({ name: obj.name, item: it, subItem: subItem, originalEvent: event }); + } + return; + } + if (it && !it.disabled) { + // event before + var edata = this.trigger({ phase: 'before', type: 'click', target: (id != null ? id : this.name), + item: it, object: it, originalEvent: event }); + if (edata.isCancelled === true) return; + + var btn = '#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button'; + $(btn).removeClass('down'); // need to requery at the moment -- as well as elsewhere in this function + + if (it.type == 'radio') { + for (var i = 0; i < this.items.length; i++) { + var itt = this.items[i]; + if (itt == null || itt.id == it.id || itt.type !== 'radio') continue; + if (itt.group == it.group && itt.checked) { + itt.checked = false; + this.refresh(itt.id); + } + } + it.checked = true; + $(btn).addClass('checked'); + } + + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1) { + obj.tooltipHide(id); + if (it.checked) { + // if it was already checked, second click will hide it + setTimeout(function () { + // hide overlay + var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id)); + el.w2overlay({ name: obj.name }); + // uncheck + it.checked = false; + obj.refresh(it.id); + }, 1); + + } else { + + // show overlay + setTimeout(function () { + var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id)); + if (!$.isPlainObject(it.overlay)) it.overlay = {}; + var left = (el.width() - 50) / 2; + if (left > 19) left = 19; + if (it.type == 'drop') { + el.w2overlay(it.html, $.extend({ name: obj.name, left: left, top: 3 }, it.overlay, { + onHide: function (event) { + hideDrop(); + } + })); + } + if (['menu', 'menu-radio', 'menu-check'].indexOf(it.type) != -1) { + var menuType = 'normal'; + if (it.type == 'menu-radio') { + menuType = 'radio'; + it.items.forEach(function (item) { + if (it.selected == item.id) item.checked = true; else item.checked = false; + }); + } + if (it.type == 'menu-check') { + menuType = 'check'; + it.items.forEach(function (item) { + if ($.isArray(it.selected) && it.selected.indexOf(item.id) != -1) item.checked = true; else item.checked = false; + }); + } + el.w2menu($.extend({ name: obj.name, items: it.items, left: left, top: 3 }, it.overlay, { + type: menuType, + select: function (event) { + obj.menuClick({ name: obj.name, item: it, subItem: event.item, originalEvent: event.originalEvent, keepOpen: event.keepOpen }); + }, + onHide: function (event) { + hideDrop(); + } + })); + } + if (['color', 'text-color'].indexOf(it.type) != -1) { + if (it.transparent == null) it.transparent = true; + $(el).w2color({ color: it.color, transparent: it.transparent }, function (color, index) { + if (color != null) { + obj.colorClick({ name: obj.name, item: it, color: color, originalEvent: event.originalEvent }); + } + hideDrop(); + }); + } + function hideDrop(event) { + it.checked = false; + $(btn).removeClass('checked'); + } + }, 1); + } + } + + if (['check', 'menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1) { + it.checked = !it.checked; + if (it.checked) { + $(btn).addClass('checked'); + } else { + $(btn).removeClass('checked'); + } + } + // route processing + if (it.route) { + var route = String('/'+ it.route).replace(/\/{2,}/g, '/'); + var info = w2utils.parseRoute(route); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); + } + } + setTimeout(function () { window.location.hash = route; }, 1); + } + if (event && ['button', 'check', 'radio'].indexOf(it.type) != -1) { + // need to refresh toolbar as it might be dynamic + this.tooltipShow(id, event, true); + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + }, + + scroll: function (direction) { + var box = $(this.box); + var obj = this; + var scrollBox = box.find('.w2ui-scroll-wrapper'); + var scrollLeft = scrollBox.scrollLeft(); + var width1, width2, scroll; + + switch (direction) { + case 'left': + width1 = scrollBox.outerWidth(); + width2 = scrollBox.find(':first').outerWidth(); + scroll = scrollLeft - width1 + 50; // 35 is width of both button + if (scroll <= 0) scroll = 0; + scrollBox.animate({ scrollLeft: scroll }, 300); + break; + + case 'right': + width1 = scrollBox.outerWidth(); + width2 = scrollBox.find(':first').outerWidth(); + scroll = scrollLeft + width1 - 50; // 35 is width of both button + if (scroll >= width2 - width1) scroll = width2 - width1; + scrollBox.animate({ scrollLeft: scroll }, 300); + break; + } + setTimeout(function () { obj.resize(); }, 350); + }, + + render: function (box) { + var time = (new Date()).getTime(); + // event before + var edata = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (edata.isCancelled === true) return; + + if (box != null) { + if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html(''); + } + this.box = box; + } + if (!this.box) return; + // render all buttons + var html = '
'+ + ''+ + ''; + for (var i = 0; i < this.items.length; i++) { + var it = this.items[i]; + if (it == null) continue; + if (it.id == null) it.id = "item_" + i; + if (it.type == 'spacer') { + html += ''; + } else { + html += ''; + } + } + html += ''; + html += ''+ + '
'+ + ''+ this.right +'
'+ + '
'+ + '
'; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-toolbar') + .html(html); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // refresh all + this.refresh(); + this.resize(); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + refresh: function (id) { + var time = (new Date()).getTime(); + // event before + var edata = this.trigger({ phase: 'before', type: 'refresh', target: (id != null ? id : this.name), item: this.get(id) }); + if (edata.isCancelled === true) return; + // refresh all + if (id == null) { + for (var i = 0; i < this.items.length; i++) { + var it1 = this.items[i]; + if (it1.id == null) it1.id = "item_" + i; + this.refresh(it1.id); + } + return; + } + // create or refresh only one item + var it = this.get(id); + if (it == null) return false; + if (typeof it.onRefresh == 'function') { + var edata2 = this.trigger({ phase: 'before', type: 'refresh', target: id, item: it, object: it }); + if (edata2.isCancelled === true) return; + } + var el = $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)); + var html = this.getItemHTML(it); + if (el.length === 0) { + // does not exist - create it + if (it.type == 'spacer') { + html = ''; + } else { + html = ''+ html + + ''; + } + if (this.get(id, true) == this.items.length-1) { + $(this.box).find('#tb_'+ this.name +'_right').before(html); + } else { + $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(this.items[parseInt(this.get(id, true))+1].id)).before(html); + } + } else { + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1 && it.checked == false) { + if ($('#w2ui-overlay-'+ this.name).length > 0) $('#w2ui-overlay-'+ this.name)[0].hide(); + } + // refresh + el.html(html); + if (it.hidden) { el.css('display', 'none'); } else { el.css('display', ''); } + if (it.disabled) { el.addClass('disabled'); } else { el.removeClass('disabled'); } + } + // event after + if (typeof it.onRefresh == 'function') { + this.trigger($.extend(edata2, { phase: 'after' })); + } + this.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + resize: function () { + var time = (new Date()).getTime(); + // event before + var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (edata.isCancelled === true) return; + + // show hide overflow buttons + var box = $(this.box); + box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide(); + var scrollBox = box.find('.w2ui-scroll-wrapper'); + if (scrollBox.find(':first').outerWidth() > scrollBox.outerWidth()) { + // we have overflowed content + if (scrollBox.scrollLeft() > 0) { + box.find('.w2ui-scroll-left').show(); + } + if (scrollBox.scrollLeft() < scrollBox.find(':first').outerWidth() - scrollBox.outerWidth()) { + box.find('.w2ui-scroll-right').show(); + } + } + + // event after + 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; + // clean up + if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html(''); + } + $(this.box).html(''); + delete w2ui[this.name]; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + // ======================================== + // --- Internal Functions + + getItemHTML: function (item) { + var html = ''; + if (item.caption != null && item.text == null) item.text = item.caption; // for backward compatibility + if (item.text == null) item.text = ''; + if (item.tooltip == null && item.hint != null) item.tooltip = item.hint; // for backward compatibility + if (item.tooltip == null) item.tooltip = ''; + var img = ' '; + var text = item.text; + if (typeof text == 'function') text = text.call(this, item); + if (item.img) img = '
'; + if (item.icon) img = '
'; + + if (html === '') switch (item.type) { + case 'color': + case 'text-color': + if (typeof item.color == 'string' && item.color.substr(0,1) == '#') item.color = item.color.substr(1); + if (item.type == 'color') { + text = '
'+ + (item.text ? '
' + w2utils.lang(item.text) + '
' : ''); + } + if (item.type == 'text-color') { + text = '
'+ + (item.text ? w2utils.lang(item.text) : 'Aa') + + '
'; + } + case 'menu': + case 'menu-check': + case 'menu-radio': + case 'button': + case 'check': + case 'radio': + case 'drop': + html += ''+ + '
'+ + ' '+ + ' ' + + img + + (text !== '' + ? '' + : '' + ) + + (item.count != null + ? '' + : '' + ) + + (((['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(item.type) != -1) && item.arrow !== false) ? + '' : '') + + '
'+ w2utils.lang(text) +''+ item.count +'
'+ + '
'; + break; + + case 'break': + html += ''+ + ' '+ + '
 
'; + break; + + case 'html': + html += ''+ + ' '+ + '
' + (typeof item.html == 'function' ? item.html.call(this, item) : item.html) + '
'; + break; + } + return '
' + html + '
'; + }, + + tooltipShow: function (id, event, forceRefresh) { + if (this.tooltip == null) return; + var $el = $(this.box).find('#tb_'+ this.name + '_item_'+ w2utils.escapeId(id)); + var item = this.get(id); + var pos = this.tooltip; + var txt = item.tooltip; + if (typeof txt == 'function') txt = txt.call(this, item); + $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 + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(item.type) != -1 && item.checked == true) return; // not for opened drop downs + $el.w2tag(w2utils.lang(txt), { position: pos }); + } + if (forceRefresh == true) { + $el.w2tag(w2utils.lang(txt), { position: pos }); + } + }, 1); + }, + + tooltipHide: function (id, event) { + if (this.tooltip == null) return; + var $el = $(this.box).find('#tb_'+ this.name + '_item_'+ w2utils.escapeId(id)); + var item = this.get(id); + $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); + }, + + menuClick: function (event) { + var obj = this; + if (event.item && !event.item.disabled) { + // event before + var edata = this.trigger({ phase: 'before', type: 'click', target: event.item.id + ':' + event.subItem.id, item: event.item, + subItem: event.subItem, originalEvent: event.originalEvent }); + if (edata.isCancelled === true) return; + + // route processing + var it = event.subItem; + var item = this.get(event.item.id); + if (item.type == 'menu-radio') { + item.selected = it.id; + event.item.items.forEach(function (item) { item.checked = false; }); + it.checked = true; + } + if (item.type == 'menu-check') { + if (!$.isArray(item.selected)) item.selected = []; + var ind = item.selected.indexOf(it.id); + if (ind == -1) { + item.selected.push(it.id); + it.checked = true; + } else { + item.selected.splice(ind, 1); + it.checked = false; + } + } + if (typeof it.route == 'string') { + var route = it.route !== '' ? String('/'+ it.route).replace(/\/{2,}/g, '/') : ''; + var info = w2utils.parseRoute(route); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + if (obj.routeData[info.keys[k].name] == null) continue; + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); + } + } + setTimeout(function () { window.location.hash = route; }, 1); + } + this.refresh(event.item.id); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + }, + + colorClick: function (event) { + var obj = this; + if (event.item && !event.item.disabled) { + // event before + var edata = this.trigger({ phase: 'before', type: 'click', target: event.item.id, item: event.item, + color: event.color, originalEvent: event.originalEvent }); + if (edata.isCancelled === true) return; + + // default behavior + event.item.color = event.color; + obj.refresh(event.item.id); + + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + } + }; + + $.extend(w2toolbar.prototype, w2utils.event); + w2obj.toolbar = w2toolbar; +})(jQuery); + +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2sidebar - sidebar widget +* - $().w2sidebar - jQuery wrapper +* - Dependencies: jQuery, w2utils +* +* == NICE TO HAVE == +* - add find() method to find nodes by a specific criteria (I want all nodes for exampe) +* - dbl click should be like it is in grid (with timer not HTML dbl click event) +* - reorder with dgrag and drop +* - node.style is misleading - should be there to apply color for example +* - add multiselect +* +************************************************************************/ + +(function ($) { + var w2sidebar = function (options) { + this.name = null; + this.box = null; + this.sidebar = null; + this.parent = null; + this.nodes = []; // Sidebar child nodes + this.menu = []; + this.routeData = {}; // data for dynamic routes + this.selected = null; // current selected node (readonly) + this.img = null; + this.icon = null; + this.style = ''; + this.topHTML = ''; + this.bottomHTML = ''; + this.flatButton = false; + this.keyboard = true; + this.flat = false; + this.hasFocus = false; + + $.extend(true, this, w2obj.sidebar, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2sidebar = function(method) { + if ($.isPlainObject(method)) { + // check name parameter + if (!w2utils.checkName(method, 'w2sidebar')) return; + // extend items + var nodes = method.nodes; + var object = new w2sidebar(method); + $.extend(object, { handlers: [], nodes: [] }); + if (nodes != null) { + object.add(object, nodes); + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + object.sidebar = object; + // register new object + w2ui[object.name] = object; + 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 + + w2sidebar.prototype = { + + onClick : null, // Fire when user click on Node Text + onDblClick : null, // Fire when user dbl clicks + onContextMenu : null, + onMenuClick : null, // when context menu item selected + onExpand : null, // Fire when node Expands + onCollapse : null, // Fire when node Colapses + onKeydown : null, + onRender : null, + onRefresh : null, + onResize : null, + onDestroy : null, + onFocus : null, + onBlur : null, + onFlat : null, + + node: { + id : null, + text : '', + count : null, + img : null, + icon : null, + nodes : [], + style : '', // additional style for subitems + route : null, + selected : false, + expanded : false, + hidden : false, + disabled : false, + group : false, // if true, it will build as a group + groupShowHide : true, + collapsible : true, + plus : false, // if true, plus will be shown even if there is no sub nodes + // events + onClick : null, + onDblClick : null, + onContextMenu : null, + onExpand : null, + onCollapse : null, + // internal + parent : null, // node object + sidebar : null + }, + + add: function (parent, nodes) { + if (arguments.length == 1) { + // need to be in reverse order + nodes = arguments[0]; + parent = this; + } + if (typeof parent == 'string') parent = this.get(parent); + return this.insert(parent, null, nodes); + }, + + insert: function (parent, before, nodes) { + var txt, ind, tmp, node, nd; + if (arguments.length == 2) { + // need to be in reverse order + nodes = arguments[1]; + before = arguments[0]; + if (before != null) { + ind = this.get(before); + if (ind == null) { + if (!$.isArray(nodes)) nodes = [nodes]; + txt = (nodes[0].caption != null ? nodes[0].caption : nodes[0].text); + console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); + return null; + } + parent = this.get(before).parent; + } else { + parent = this; + } + } + if (typeof parent == 'string') parent = this.get(parent); + if (!$.isArray(nodes)) nodes = [nodes]; + for (var o = 0; o < nodes.length; o++) { + node = nodes[o]; + if (typeof node.id == null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.'); + continue; + } + if (this.get(this, node.id) != null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node with id='+ node.id +' (text: '+ txt + ') because another node with the same id already exists.'); + continue; + } + tmp = $.extend({}, w2sidebar.prototype.node, node); + tmp.sidebar = this; + tmp.parent = parent; + nd = tmp.nodes || []; + tmp.nodes = []; // very important to re-init empty nodes array + if (before == null) { // append to the end + parent.nodes.push(tmp); + } else { + ind = this.get(parent, before, true); + if (ind == null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); + return null; + } + parent.nodes.splice(ind, 0, tmp); + } + if (nd.length > 0) { + this.insert(tmp, null, nd); + } + } + this.refresh(parent.id); + return tmp; + }, + + remove: function () { // multiple arguments + var deleted = 0; + var tmp; + for (var a = 0; a < arguments.length; a++) { + tmp = this.get(arguments[a]); + if (tmp == null) continue; + if (this.selected != null && this.selected === tmp.id) { + this.selected = null; + } + var ind = this.get(tmp.parent, arguments[a], true); + if (ind == null) continue; + if (tmp.parent.nodes[ind].selected) tmp.sidebar.unselect(tmp.id); + tmp.parent.nodes.splice(ind, 1); + deleted++; + } + if (deleted > 0 && arguments.length == 1) this.refresh(tmp.parent.id); else this.refresh(); + return deleted; + }, + + set: function (parent, id, node) { + if (arguments.length == 2) { + // need to be in reverse order + node = id; + id = parent; + parent = this; + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return null; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id === id) { + // make sure nodes inserted correctly + var nodes = node.nodes; + $.extend(parent.nodes[i], node, { nodes: [] }); + if (nodes != null) { + this.add(parent.nodes[i], nodes); + } + this.refresh(id); + return true; + } else { + var rv = this.set(parent.nodes[i], id, node); + if (rv) return true; + } + } + return false; + }, + + get: function (parent, id, returnIndex) { // can be just called get(id) or get(id, true) + if (arguments.length === 0) { + var all = []; + var tmp = this.find({}); + for (var t = 0; t < tmp.length; t++) { + if (tmp[t].id != null) all.push(tmp[t].id); + } + return all; + } else { + if (arguments.length == 1 || (arguments.length == 2 && id === true) ) { + // need to be in reverse order + returnIndex = id; + id = parent; + parent = this; + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return null; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id == id) { + if (returnIndex === true) return i; else return parent.nodes[i]; + } else { + var rv = this.get(parent.nodes[i], id, returnIndex); + if (rv || rv === 0) return rv; + } + } + return null; + } + }, + + find: function (parent, params, results) { // can be just called find({ selected: true }) + if (arguments.length == 1) { + // need to be in reverse order + params = parent; + parent = this; + } + if (!results) results = []; + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return results; + for (var i = 0; i < parent.nodes.length; i++) { + var match = true; + for (var prop in params) { // params is an object + if (parent.nodes[i][prop] != params[prop]) match = false; + } + if (match) results.push(parent.nodes[i]); + if (parent.nodes[i].nodes.length > 0) results = this.find(parent.nodes[i], params, results); + } + return results; + }, + + hide: function () { // multiple arguments + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp == null) continue; + tmp.hidden = true; + hidden++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return hidden; + }, + + show: function () { // multiple arguments + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp == null) continue; + tmp.hidden = false; + shown++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return shown; + }, + + disable: function () { // multiple arguments + var disabled = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp == null) continue; + tmp.disabled = true; + if (tmp.selected) this.unselect(tmp.id); + disabled++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return disabled; + }, + + enable: function () { // multiple arguments + var enabled = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp == null) continue; + tmp.disabled = false; + enabled++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return enabled; + }, + + select: function (id) { + var new_node = this.get(id); + if (!new_node) return false; + if (this.selected == id && new_node.selected) return false; + this.unselect(this.selected); + $(this.box).find('#node_'+ w2utils.escapeId(id)) + .addClass('w2ui-selected') + .find('.w2ui-icon').addClass('w2ui-icon-selected'); + new_node.selected = true; + this.selected = id; + return true; + }, + + unselect: function (id) { + // if no arguments provided, unselect selected node + if (arguments.length === 0) { + id = this.selected; + } + var current = this.get(id); + if (!current) return false; + current.selected = false; + $(this.box).find('#node_'+ w2utils.escapeId(id)) + .removeClass('w2ui-selected') + .find('.w2ui-icon').removeClass('w2ui-icon-selected'); + if (this.selected == id) this.selected = null; + return true; + }, + + toggle: function(id) { + var nd = this.get(id); + if (nd == null) return false; + if (nd.plus) { + this.set(id, { plus: false }); + this.expand(id); + this.refresh(id); + return; + } + if (nd.nodes.length === 0) return false; + if (!nd.collapsible) return false; + if (this.get(id).expanded) return this.collapse(id); else return this.expand(id); + }, + + collapse: function (id) { + var obj = this; + var nd = this.get(id); + // event before + var edata = this.trigger({ phase: 'before', type: 'collapse', target: id, object: nd }); + if (edata.isCancelled === true) return; + // default action + $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideUp(200); + $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
+
'); + nd.expanded = false; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + setTimeout(function () { obj.refresh(id); }, 200); + return true; + }, + + collapseAll: function (parent) { + if (parent == null) parent = this; + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return false; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === true) parent.nodes[i].expanded = false; + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); + } + this.refresh(parent.id); + return true; + }, + + expand: function (id) { + var obj = this; + var nd = this.get(id); + // event before + var edata = this.trigger({ phase: 'before', type: 'expand', target: id, object: nd }); + if (edata.isCancelled === true) return; + // default action + $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideDown(200); + $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
-
'); + nd.expanded = true; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + setTimeout(function () { obj.refresh(id); }, 200); + return true; + }, + + expandAll: function (parent) { + if (parent == null) parent = this; + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return false; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === false) parent.nodes[i].expanded = true; + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.expandAll(parent.nodes[i]); + } + this.refresh(parent.id); + }, + + expandParents: function (id) { + var node = this.get(id); + if (node == null) return false; + if (node.parent) { + if (!node.parent.expanded) { + node.parent.expanded = true; + this.refresh(node.parent.id); + } + this.expandParents(node.parent.id); + } + return true; + }, + + click: function (id, event) { + var obj = this; + var nd = this.get(id); + if (nd == null) return; + if (nd.disabled || nd.group) return; // should click event if already selected + // unselect all previsously + $(obj.box).find('.w2ui-node.w2ui-selected').each(function (index, el) { + var oldID = $(el).attr('id').replace('node_', ''); + var oldNode = obj.get(oldID); + if (oldNode != null) oldNode.selected = false; + $(el).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); + }); + // select new one + var newNode = $(obj.box).find('#node_'+ w2utils.escapeId(id)); + var oldNode = $(obj.box).find('#node_'+ w2utils.escapeId(obj.selected)); + newNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); + // need timeout to allow rendering + setTimeout(function () { + // event before + var edata = obj.trigger({ phase: 'before', type: 'click', target: id, originalEvent: event, node: nd, object: nd }); + if (edata.isCancelled === true) { + // restore selection + newNode.removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); + oldNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); + return; + } + // default action + if (oldNode != null) oldNode.selected = false; + obj.get(id).selected = true; + obj.selected = id; + // route processing + if (typeof nd.route == 'string') { + var route = nd.route !== '' ? String('/'+ nd.route).replace(/\/{2,}/g, '/') : ''; + var info = w2utils.parseRoute(route); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + if (obj.routeData[info.keys[k].name] == null) continue; + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), obj.routeData[info.keys[k].name]); + } + } + setTimeout(function () { window.location.hash = route; }, 1); + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, 1); + }, + + 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).find('.w2ui-selected').removeClass('w2ui-inactive'); + setTimeout(function () { + var $input = $(obj.box).find('#sidebar_'+ 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).find('.w2ui-selected').addClass('w2ui-inactive'); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + keydown: function (event) { + var obj = this; + var nd = obj.get(obj.selected); + if (obj.keyboard !== true) return; + if (!nd) nd = obj.nodes[0]; + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); + if (edata.isCancelled === true) return; + // default behaviour + if (event.keyCode == 13 || event.keyCode == 32) { // enter or space + if (nd.nodes.length > 0) obj.toggle(obj.selected); + } + if (event.keyCode == 37) { // left + if (nd.nodes.length > 0 && nd.expanded) { + obj.collapse(obj.selected); + } else { + selectNode(nd.parent); + if (!nd.parent.group) obj.collapse(nd.parent.id); + } + } + if (event.keyCode == 39) { // right + if ((nd.nodes.length > 0 || nd.plus) && !nd.expanded) obj.expand(obj.selected); + } + if (event.keyCode == 38) { // up + selectNode(neighbor(nd, prev)); + } + if (event.keyCode == 40) { // down + selectNode(neighbor(nd, next)); + } + // cancel event if needed + if ($.inArray(event.keyCode, [13, 32, 37, 38, 39, 40]) != -1) { + if (event.preventDefault) event.preventDefault(); + if (event.stopPropagation) event.stopPropagation(); + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + + function selectNode (node, event) { + if (node != null && !node.hidden && !node.disabled && !node.group) { + obj.click(node.id, event); + setTimeout(function () { obj.scrollIntoView(); }, 50); + } + } + + function neighbor (node, neighborFunc) { + node = neighborFunc(node); + while (node != null && (node.hidden || node.disabled)) { + if (node.group) break; else node = neighborFunc(node); + } + return node; + } + + function next (node, noSubs) { + if (node == null) return null; + var parent = node.parent; + var ind = obj.get(node.id, true); + var nextNode = null; + // jump inside + if (node.expanded && node.nodes.length > 0 && noSubs !== true) { + var t = node.nodes[0]; + if (t.hidden || t.disabled || t.group) nextNode = next(t); else nextNode = t; + } else { + if (parent && ind + 1 < parent.nodes.length) { + nextNode = parent.nodes[ind + 1]; + } else { + nextNode = next(parent, true); // jump to the parent + } + } + if (nextNode != null && (nextNode.hidden || nextNode.disabled || nextNode.group)) nextNode = next(nextNode); + return nextNode; + } + + function prev (node) { + if (node == null) return null; + var parent = node.parent; + var ind = obj.get(node.id, true); + var prevNode = (ind > 0) ? lastChild(parent.nodes[ind - 1]) : parent; + if (prevNode != null && (prevNode.hidden || prevNode.disabled || prevNode.group)) prevNode = prev(prevNode); + return prevNode; + } + + function lastChild (node) { + if (node.expanded && node.nodes.length > 0) { + var t = node.nodes[node.nodes.length - 1]; + if (t.hidden || t.disabled || t.group) return prev(t); else return lastChild(t); + } + return node; + } + }, + + scrollIntoView: function (id) { + if (id == null) id = this.selected; + var nd = this.get(id); + if (nd == null) return; + var body = $(this.box).find('.w2ui-sidebar-div'); + var item = $(this.box).find('#node_'+ w2utils.escapeId(id)); + var offset = item.offset().top - body.offset().top; + if (offset + item.height() > body.height() || offset <= 0) { + body.animate({ 'scrollTop': body.scrollTop() + offset - body.height() / 2 + item.height() }, 250, 'linear'); + } + }, + + dblClick: function (id, event) { + var nd = this.get(id); + // event before + var edata = this.trigger({ phase: 'before', type: 'dblClick', target: id, originalEvent: event, object: nd }); + if (edata.isCancelled === true) return; + // default action + this.toggle(id); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + contextMenu: function (id, event) { + var obj = this; + var nd = obj.get(id); + if (id != obj.selected) obj.click(id); + // event before + var edata = obj.trigger({ phase: 'before', type: 'contextMenu', target: id, originalEvent: event, object: nd, allowOnDisabled: false }); + if (edata.isCancelled === true) return; + // default action + if (nd.disabled && !edata.allowOnDisabled) return; + if (obj.menu.length > 0) { + $(obj.box).find('#node_'+ w2utils.escapeId(id)) + .w2menu({ + items: obj.menu, + contextMenu: true, + originalEvent: event, + onSelect: function (event) { + obj.menuClick(id, parseInt(event.index), event.originalEvent); + } + } + ); + } + // cancel event + if (event.preventDefault) event.preventDefault(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, + + menuClick: function (itemId, index, event) { + var obj = this; + // event before + var edata = obj.trigger({ phase: 'before', type: 'menuClick', target: itemId, originalEvent: event, menuIndex: index, menuItem: obj.menu[index] }); + if (edata.isCancelled === true) return; + // default action + // -- empty + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, + + goFlat: function () { + // event before + var edata = this.trigger({ phase: 'before', type: 'flat', goFlat: !this.flat }); + if (edata.isCancelled === true) return; + // default action + this.flat = !this.flat; + this.refresh(); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + render: function (box) { + var time = (new Date()).getTime(); + var obj = this; + // event before + var edata = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (edata.isCancelled === true) return; + // default action + if (box != null) { + if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html(''); + } + this.box = box; + } + if (!this.box) return; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-sidebar') + .html('
'+ + ''+ + '
' + + '
'+ + '
'+ + '
' + ); + $(this.box).find('> div').css({ + width : $(this.box).width() + 'px', + height : $(this.box).height() + 'px' + }); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // adjust top and bottom + var flatHTML = ''; + if (this.flatButton == true) { + flatHTML = '
'; + } + if (this.topHTML !== '' || flatHTML !== '') { + $(this.box).find('.w2ui-sidebar-top').html(this.topHTML + flatHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); + } + if (this.bottomHTML !== '') { + $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); + } + // focus + var kbd_timer; + $(this.box).find('#sidebar_'+ this.name + '_focus') + .on('focus', function (event) { + clearTimeout(kbd_timer); + if (!obj.hasFocus) obj.focus(event); + }) + .on('blur', function (event) { + kbd_timer = setTimeout(function () { + if (obj.hasFocus) { obj.blur(event); } + }, 100); + }) + .on('keydown', function (event) { + if (event.keyCode != 9) { // not tab + w2ui[obj.name].keydown.call(w2ui[obj.name], event); + } + }); + $(this.box).off('mousedown').on('mousedown', function (event) { + // set focus to grid + setTimeout(function () { + // if input then do not focus + if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName.toUpperCase()) == -1) { + var $input = $(obj.box).find('#sidebar_'+ obj.name + '_focus'); + if (!$input.is(':focus')) { + if ($(event.target).hasClass('w2ui-node')) { + var top = $(event.target).position().top + $(obj.box).find('.w2ui-sidebar-top').height() + event.offsetY; + $input.css({ top: top + 'px', left: '0px' }); + } + $input.focus(); + } + } + }, 1); + }); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + // --- + this.refresh(); + return (new Date()).getTime() - time; + }, + + refresh: function (id) { + var time = (new Date()).getTime(); + // event before + var edata = this.trigger({ phase: 'before', type: 'refresh', target: (id != null ? id : this.name), + fullRefresh: (id != null ? false : true) }); + if (edata.isCancelled === true) return; + // adjust top and bottom + var flatHTML = ''; + if (this.flatButton == true) { + flatHTML = '
'; + } + if (this.topHTML !== '' || flatHTML !== '') { + $(this.box).find('.w2ui-sidebar-top').html(this.topHTML + flatHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); + } + if (this.bottomHTML !== '') { + $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); + } + // default action + $(this.box).find('> div').removeClass('w2ui-sidebar-flat').addClass(this.flat ? 'w2ui-sidebar-flat' : '').css({ + width : $(this.box).width() + 'px', + height: $(this.box).height() + 'px' + }); + var obj = this; + var node, nd; + var nm; + if (id == null) { + node = this; + nm = '.w2ui-sidebar-div'; + } else { + node = this.get(id); + if (node == null) return; + nm = '#node_'+ w2utils.escapeId(node.id) + '_sub'; + } + var nodeHTML; + if (node !== this) { + var tmp = '#node_'+ w2utils.escapeId(node.id); + nodeHTML = getNodeHTML(node); + $(this.box).find(tmp).before(''); + $(this.box).find(tmp).remove(); + $(this.box).find(nm).remove(); + $('#sidebar_'+ this.name + '_tmp').before(nodeHTML); + $('#sidebar_'+ this.name + '_tmp').remove(); + } + // refresh sub nodes + $(this.box).find(nm).html(''); + for (var i = 0; i < node.nodes.length; i++) { + nd = node.nodes[i]; + nodeHTML = getNodeHTML(nd); + $(this.box).find(nm).append(nodeHTML); + if (nd.nodes.length !== 0) { + this.refresh(nd.id); + } else { + // trigger event + var edata2 = this.trigger({ phase: 'before', type: 'refresh', target: nd.id }); + if (edata2.isCancelled === true) return; + // event after + this.trigger($.extend(edata2, { phase: 'after' })); + } + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + + function getNodeHTML(nd) { + var html = ''; + var img = nd.img; + if (img == null) img = this.img; + var icon = nd.icon; + if (icon == null) icon = this.icon; + // -- find out level + var tmp = nd.parent; + var level = 0; + while (tmp && tmp.parent != null) { + if (tmp.group) level--; + tmp = tmp.parent; + level++; + } + if (nd.caption != null) nd.text = nd.caption; + if (nd.group) { + html = + '
'+ + ((nd.groupShowHide && nd.collapsible) ? ''+ (!nd.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')) +'' : '') + + (typeof nd.text == 'function' ? nd.text.call(obj, nd) : ''+ nd.text +'') + + '
'+ + '
'; + if (obj.flat) { + html = '
 
'+ + '
'; + } + } else { + if (nd.selected && !nd.disabled) obj.selected = nd.id; + tmp = ''; + if (img) tmp = '
'; + if (icon) tmp = '
'; + var text = nd.text; + if (typeof nd.text == 'function') text = nd.text.call(obj, nd); + html = '
'+ + ''+ + ''+ + ''+ + '
'+ + '
' + (nd.nodes.length > 0 ? (nd.expanded ? '-' : '+') : (nd.plus ? '+' : '')) + '
' + + '
'+ + tmp + + (nd.count || nd.count === 0 ? '
'+ nd.count +'
' : '') + + '
'+ text +'
'+ + '
'+ + '
'+ + '
'; + if (obj.flat) { + html = '
'+ nd.count +'' : '')) + '\'), '+ + ' { id: \'' + nd.id + '\', left: -5 })"'+ + ' onmouseout="jQuery(this).find(\'.w2ui-node-data\').w2tag(null, { id: \'' + nd.id + '\' })"'+ + ' ondblclick="w2ui[\''+ obj.name +'\'].dblClick(\''+ nd.id +'\', event);"'+ + ' oncontextmenu="w2ui[\''+ obj.name +'\'].contextMenu(\''+ nd.id +'\', event);"'+ + ' onClick="w2ui[\''+ obj.name +'\'].click(\''+ nd.id +'\', event); ">'+ + '
'+ tmp +'
'+ + '
'+ + '
'; + } + } + return html; + } + }, + + resize: function () { + var time = (new Date()).getTime(); + // event before + var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (edata.isCancelled === true) return; + // default action + $(this.box).css('overflow', 'hidden'); // container should have no overflow + $(this.box).find('> div').css({ + width : $(this.box).width() + 'px', + height : $(this.box).height() + 'px' + }); + // event after + 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; + // clean up + if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + lock: function (msg, showSpinner) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(this.box); + w2utils.lock.apply(window, args); + }, + + unlock: function (speed) { + w2utils.unlock(this.box, speed); + } + }; + + $.extend(w2sidebar.prototype, w2utils.event); + w2obj.sidebar = w2sidebar; +})(jQuery); + +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2field - various field controls +* - $().w2field - jQuery wrapper +* - Dependencies: jQuery, w2utils +* +* == NICE TO HAVE == +* - upload (regular files) +* - BUG with prefix/postfix and arrows (test in different contexts) +* - multiple date selection +* - month selection, year selections +* - arrows no longer work (for int) +* - form to support custom types +* - rewrite suffix and prefix positioning with translateY() +* - prefix and suffix are slow (100ms or so) +* - MultiSelect - Allow Copy/Paste for single and multi values +* - add routeData to list/enum +* - for type: list -> read value from attr('value') +* - ENUM, LIST: should have same as grid (limit, offset, search, sort) +* - ENUM, LIST: should support wild chars +* - add selection of predefined times (used for appointments) +* +************************************************************************/ + +(function ($) { + + var w2field = function (options) { + // public properties + this.el = null; + this.helpers = {}; // object or helper elements + this.type = options.type || 'text'; + this.options = $.extend(true, {}, options); + this.onSearch = options.onSearch || null; + this.onRequest = options.onRequest || null; + this.onLoad = options.onLoad || null; + this.onError = options.onError || null; + this.onClick = options.onClick || null; + this.onAdd = options.onAdd || null; + this.onNew = options.onNew || null; + this.onRemove = options.onRemove || null; + this.onMouseOver = options.onMouseOver || null; + this.onMouseOut = options.onMouseOut || null; + this.onIconClick = options.onIconClick || null; + this.onScroll = options.onScroll || null; + this.tmp = {}; // temp object + // clean up some options + delete this.options.type; + delete this.options.onSearch; + delete this.options.onRequest; + delete this.options.onLoad; + delete this.options.onError; + delete this.options.onClick; + delete this.options.onMouseOver; + delete this.options.onMouseOut; + delete this.options.onIconClick; + delete this.options.onScroll; + // extend with defaults + $.extend(true, this, w2obj.field); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2field = function (method, options) { + // call direct + if (this.length === 0) { + var pr = w2field.prototype; + if (pr[method]) { + return pr[method].apply(pr, Array.prototype.slice.call(arguments, 1)); + } + } else { + // if without arguments - return the object + if (arguments.length === 0) { + var obj = $(this).data('w2field'); + return obj; + } + if (typeof method == 'string' && typeof options == 'object') { + method = $.extend(true, {}, options, { type: method }); + } + if (typeof method == 'string' && options == null) { + method = { type: method }; + } + method.type = String(method.type).toLowerCase(); + return this.each(function (index, el) { + var obj = $(el).data('w2field'); + // if object is not defined, define it + if (obj == null) { + var obj = new w2field(method); + $.extend(obj, { handlers: [] }); + if (el) obj.el = $(el)[0]; + obj.init(); + $(el).data('w2field', obj); + return obj; + } else { // fully re-init + obj.clear(); + if (method.type == 'clear') return; + var obj = new w2field(method); + $.extend(obj, { handlers: [] }); + if (el) obj.el = $(el)[0]; + obj.init(); + $(el).data('w2field', obj); + return obj; + } + return null; + }); + } + }; + + // ==================================================== + // -- Implementation of core functionality + + /* To add custom types + $().w2field('addType', 'myType', function (options) { + $(this.el).on('keypress', function (event) { + if (event.metaKey || event.ctrlKey || event.altKey + || (event.charCode != event.keyCode && event.keyCode > 0)) return; + var ch = String.fromCharCode(event.charCode); + if (ch != 'a' && ch != 'b' && ch != 'c') { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + return false; + } + }); + $(this.el).on('blur', function (event) { // keyCode & charCode differ in FireFox + var ch = this.value; + if (ch != 'a' && ch != 'b' && ch != 'c') { + $(this).w2tag(w2utils.lang("Not a single character from the set of 'abc'")); + } + }); + }); + */ + + w2field.prototype = { + + custom: {}, // map of custom types + + addType: function (type, handler) { + type = String(type).toLowerCase(); + this.custom[type] = handler; + return true; + }, + + removeType: function (type) { + type = String(type).toLowerCase(); + if (!this.custom[type]) return false; + delete this.custom[type]; + return true; + }, + + init: function () { + var obj = this; + var options = this.options; + var defaults; + + // Custom Types + if (typeof this.custom[this.type] == 'function') { + this.custom[this.type].call(this, options); + return; + } + // only for INPUT or TEXTAREA + if (['INPUT', 'TEXTAREA'].indexOf(this.el.tagName.toUpperCase()) == -1) { + console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el); + return; + } + + switch (this.type) { + case 'text': + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'alphanumeric': + case 'bin': + case 'hex': + defaults = { + min : null, + max : null, + step : 1, + autoFormat : true, + currencyPrefix : w2utils.settings.currencyPrefix, + currencySuffix : w2utils.settings.currencySuffix, + currencyPrecision : w2utils.settings.currencyPrecision, + decimalSymbol : w2utils.settings.decimalSymbol, + groupSymbol : w2utils.settings.groupSymbol, + arrows : false, + keyboard : true, + precision : null, + silent : true, + prefix : '', + suffix : '' + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g'); + options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol +']', 'g'); + options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g'); + // no keyboard support needed + if (['text', 'alphanumeric', 'hex', 'bin'].indexOf(this.type) != -1) { + options.arrows = false; + options.keyboard = false; + } + this.addPrefix(); // only will add if needed + this.addSuffix(); + break; + + case 'color': + defaults = { + prefix : '#', + suffix : '
 
', + arrows : false, + keyboard : false, + transparent : true + }; + $.extend(options, defaults); + this.addPrefix(); // only will add if needed + this.addSuffix(); // only will add if needed + // additional checks + $(this.el).attr('maxlength', 6); + if ($(this.el).val() !== '') setTimeout(function () { obj.change(); }, 1); + break; + + case 'date': + defaults = { + format : w2utils.settings.dateFormat, // date format + keyboard : true, + silent : true, + start : '', // string or jquery object + end : '', // string or jquery object + blocked : {}, // { '4/11/2011': 'yes' } + colored : {}, // { '4/11/2011': 'red:white' } + blockWeekDays : null // array of numbers of weekday to block + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.format); + break; + + case 'time': + defaults = { + format : w2utils.settings.timeFormat, + keyboard : true, + silent : true, + start : '', + end : '', + noMinutes : false + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.format); + break; + + case 'datetime': + defaults = { + format : w2utils.settings.dateFormat + ' | ' + w2utils.settings.timeFormat, + keyboard : true, + silent : true, + start : '', // string or jquery object or Date object + end : '', // string or jquery object or Date object + blocked : [], // [ '4/11/2011', '4/12/2011' ] or [ new Date(2011, 4, 11), new Date(2011, 4, 12) ] + colored : {}, // { '12/17/2014': 'blue:green', '12/18/2014': 'gray:white' }; // key has to be formatted with w2utils.settings.dateFormat + placeholder : null, // optional. will fall back to this.format if not specified. Only used if this.el has no placeholder attribute. + btn_now : true, // show/hide the use-current-date-and-time button + noMinutes : false + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.placeholder || options.format); + break; + + case 'list': + case 'combo': + defaults = { + items : [], + selected : {}, + url : null, // url to pull data from + recId : null, // map retrieved data from url to id, can be string or function + recText : null, // map retrieved data from url to text, can be string or function + method : null, // default comes from w2utils.settings.dataType + interval : 350, // number of ms to wait before sending server call on search + postData : {}, + minLength : 1, // min number of chars when trigger search + cacheMax : 250, + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + match : 'begins', // ['contains', 'is', 'begins', 'ends'] + silent : true, + icon : null, + iconStyle : '', + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null, // when data fails to load due to server error or other failure modes + onIconClick : null, + renderDrop : null, // render function for drop down item + compare : null, // compare function for filtering + filter : true, // weather to filter at all + prefix : '', + suffix : '', + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : false + }; + options.items = this.normMenu(options.items); // need to be first + if (this.type == 'list') { + // defaults.search = (options.items && options.items.length >= 10 ? true : false); + defaults.openOnFocus = true; + $(this.el).addClass('w2ui-select'); + // if simple value - look it up + if (!$.isPlainObject(options.selected) && options.items) { + for (var i = 0; i< options.items.length; i++) { + var item = options.items[i]; + if (item && item.id == options.selected) { + options.selected = $.extend(true, {}, item); + break; + } + } + } + this.watchSize(); + } + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + altRows : true // alternate row color + }); + this.options = options; + if (!$.isPlainObject(options.selected)) options.selected = {}; + $(this.el).data('selected', options.selected); + if (options.url) { + options.items = []; + this.request(0); + } + if (this.type == 'list') this.addFocus(); + this.addPrefix(); + this.addSuffix(); + setTimeout(function () { obj.refresh(); }, 10); // need this for icon refresh + $(this.el).attr('autocomplete', 'off'); + if (options.selected.text != null) $(this.el).val(options.selected.text); + break; + + case 'enum': + defaults = { + items : [], + selected : [], + max : 0, // max number of selected items, 0 - unlim + url : null, // not implemented + recId : null, // map retrieved data from url to id, can be string or function + recText : null, // map retrieved data from url to text, can be string or function + interval : 350, // number of ms to wait before sending server call on search + method : null, // default comes from w2utils.settings.dataType + postData : {}, + minLength : 1, // min number of chars when trigger search + cacheMax : 250, + maxWidth : 250, // max width for a single item + maxHeight : 350, // max height for input control to grow + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + match : 'contains', // ['contains', 'is', 'begins', 'ends'] + silent : true, + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : true, + renderDrop : null, // render function for drop down item + renderItem : null, // render selected item + compare : null, // compare function for filtering + filter : true, // alias for compare + style : '', // style for container div + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null, // when data fails to load due to server error or other failure modes + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onNew : null, // when new item should be added + onRemove : null, // when an item is removed + onMouseOver : null, // when an item is mouse over + onMouseOut : null, // when an item is mouse out + onScroll : null // when div with selected items is scrolled + }; + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + suffix : '', + altRows : true // alternate row color + }); + options.items = this.normMenu(options.items); + options.selected = this.normMenu(options.selected); + this.options = options; + if (!$.isArray(options.selected)) options.selected = []; + $(this.el).data('selected', options.selected); + if (options.url) { + options.items = []; + this.request(0); + } + this.addSuffix(); + this.addMulti(); + this.watchSize(); + break; + + case 'file': + defaults = { + selected : [], + max : 0, + maxSize : 0, // max size of all files, 0 - unlim + maxFileSize : 0, // max size of a single file, 0 -unlim + maxWidth : 250, // max width for a single item + maxHeight : 350, // max height for input control to grow + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + readContent : true, // if true, it will readAsDataURL content of the file + silent : true, + renderItem : null, // render selected item + style : '', // style for container div + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onRemove : null, // when an item is removed + onMouseOver : null, // when an item is mouse over + onMouseOut : null // when an item is mouse out + }; + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + altRows : true // alternate row color + }); + this.options = options; + if (!$.isArray(options.selected)) options.selected = []; + $(this.el).data('selected', options.selected); + if ($(this.el).attr('placeholder') == null) { + $(this.el).attr('placeholder', w2utils.lang('Attach files by dragging and dropping or Click to Select')); + } + this.addMulti(); + this.watchSize(); + break; + } + // attach events + this.tmp = { + onChange : function (event) { obj.change.call(obj, event); }, + onClick : function (event) { obj.click.call(obj, event); }, + onFocus : function (event) { obj.focus.call(obj, event); }, + onBlur : function (event) { obj.blur.call(obj, event); }, + onKeydown : function (event) { obj.keyDown.call(obj, event); }, + onKeyup : function (event) { obj.keyUp.call(obj, event); }, + onKeypress : function (event) { obj.keyPress.call(obj, event); } + }; + $(this.el) + .addClass('w2field w2ui-input') + .data('w2field', this) + .on('change.w2field', this.tmp.onChange) + .on('click.w2field', this.tmp.onClick) // ignore click because it messes overlays + .on('focus.w2field', this.tmp.onFocus) + .on('blur.w2field', this.tmp.onBlur) + .on('keydown.w2field', this.tmp.onKeydown) + .on('keyup.w2field', this.tmp.onKeyup) + .on('keypress.w2field', this.tmp.onKeypress) + .css(w2utils.cssPrefix('box-sizing', 'border-box')); + // format initial value + this.change($.Event('change')); + }, + + watchSize: function () { + var obj = this; + var tmp = $(obj.el).data('tmp') || {}; + tmp.sizeTimer = setInterval(function () { + if ($(obj.el).parents('body').length > 0) { + obj.resize(); + } else { + clearInterval(tmp.sizeTimer); + } + }, 200); + $(obj.el).data('tmp', tmp); + }, + + get: function () { + var ret; + if (['list', 'enum', 'file'].indexOf(this.type) != -1) { + ret = $(this.el).data('selected'); + } else { + ret = $(this.el).val(); + } + return ret; + }, + + set: function (val, append) { + if (['list', 'enum', 'file'].indexOf(this.type) != -1) { + if (this.type != 'list' && append) { + if ($(this.el).data('selected') == null) $(this.el).data('selected', []); + $(this.el).data('selected').push(val); + $(this.el).change(); + } else { + var it = (this.type == 'enum' ? [val] : val); + $(this.el).data('selected', it).change(); + } + this.refresh(); + } else { + $(this.el).val(val); + } + }, + + setIndex: function (ind, append) { + if (['list', 'enum'].indexOf(this.type) != -1) { + var items = this.options.items; + if (items && items[ind]) { + if (this.type != 'list' && append) { + if ($(this.el).data('selected') == null) $(this.el).data('selected', []); + $(this.el).data('selected').push(items[ind]); + $(this.el).change(); + } else { + var it = (this.type == 'enum' ? [items[ind]] : items[ind]); + $(this.el).data('selected', it).change(); + } + this.refresh(); + return true; + } + } + return false; + }, + + clear: function () { + var obj = this; + var options = this.options; + // if money then clear value + if (['money', 'currency'].indexOf(this.type) != -1) { + $(this.el).val($(this.el).val().replace(options.moneyRE, '')); + } + if (this.type == 'percent') { + $(this.el).val($(this.el).val().replace(/%/g, '')); + } + if (this.type == 'color') { + $(this.el).removeAttr('maxlength'); + } + if (this.type == 'list') { + $(this.el).removeClass('w2ui-select'); + } + this.type = 'clear'; + var tmp = $(this.el).data('tmp'); + if (!this.tmp) return; + // restore paddings + if (tmp != null) { + $(this.el).height('auto'); + if (tmp && tmp['old-padding-left']) $(this.el).css('padding-left', tmp['old-padding-left']); + if (tmp && tmp['old-padding-right']) $(this.el).css('padding-right', tmp['old-padding-right']); + if (tmp && tmp['old-background-color']) $(this.el).css('background-color', tmp['old-background-color']); + if (tmp && tmp['old-border-color']) $(this.el).css('border-color', tmp['old-border-color']); + // remove resize watcher + clearInterval(tmp.sizeTimer); + } + // remove events and (data) + $(this.el) + .val(this.clean($(this.el).val())) + .removeClass('w2field') + .removeData() // removes all attached data + .off('.w2field'); // remove only events added by w2field + // remove helpers + for (var h in this.helpers) $(this.helpers[h]).remove(); + this.helpers = {}; + }, + + refresh: function () { + var obj = this; + var options = this.options; + var selected = $(this.el).data('selected'); + var time = (new Date()).getTime(); + // enum + if (['list'].indexOf(this.type) != -1) { + $(obj.el).parent().css('white-space', 'nowrap'); // needs this for arrow always to appear on the right side + // hide focus and show text + if (obj.helpers.prefix) obj.helpers.prefix.hide(); + setTimeout(function () { + if (!obj.helpers.focus) return; + // if empty show no icon + if (!$.isEmptyObject(selected) && options.icon) { + options.prefix = ''+ + ''; + obj.addPrefix(); + } else { + options.prefix = ''; + obj.addPrefix(); + } + // focus helper + var focus = obj.helpers.focus.find('input'); + if ($(focus).val() === '') { + $(focus).css('text-indent', '-9999em').prev().css('opacity', 0); + $(obj.el).val(selected && selected.text != null ? w2utils.lang(selected.text) : ''); + } else { + $(focus).css('text-indent', 0).prev().css('opacity', 1); + $(obj.el).val(''); + setTimeout(function () { + if (obj.helpers.prefix) obj.helpers.prefix.hide(); + var tmp = 'position: absolute; opacity: 0; margin: 4px 0px 0px 2px; background-position: left !important;'; + if (options.icon) { + $(focus).css('margin-left', '17px'); + $(obj.helpers.focus).find('.icon-search').attr('style', tmp + 'width: 11px !important; opacity: 1; display: block'); + } else { + $(focus).css('margin-left', '0px'); + $(obj.helpers.focus).find('.icon-search').attr('style', tmp + 'width: 0px !important; opacity: 0; display: none'); + } + }, 1); + } + // if readonly or disabled + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) { + setTimeout(function () { + $(obj.helpers.prefix).css('opacity', '0.6'); + $(obj.helpers.suffix).css('opacity', '0.6'); + }, 1); + } else { + setTimeout(function () { + $(obj.helpers.prefix).css('opacity', '1'); + $(obj.helpers.suffix).css('opacity', '1'); + }, 1); + } + }, 1); + } + if (['enum', 'file'].indexOf(this.type) != -1) { + var html = ''; + if (selected) { + for (var s = 0; s < selected.length; s++) { + var it = selected[s]; + var ren = ''; + if (typeof options.renderItem == 'function') { + ren = options.renderItem(it, s, '
  
'); + } else { + ren = '
  
'+ + (obj.type == 'enum' ? it.text : it.name + ' - '+ w2utils.formatSize(it.size) +''); + } + html += '
  • '+ + ren +'
  • '; + } + } + var div = obj.helpers.multi; + var ul = div.find('ul'); + div.attr('style', div.attr('style') + ';' + options.style); + $(obj.el).css('z-index', '-1'); + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) { + setTimeout(function () { + div[0].scrollTop = 0; // scroll to the top + div.addClass('w2ui-readonly') + .find('li').css('opacity', '0.9') + .parent().find('li.nomouse').hide() + .find('input').prop('readonly', true) + .parents('ul') + .find('.w2ui-list-remove').hide(); + }, 1); + } else { + setTimeout(function () { + div.removeClass('w2ui-readonly') + .find('li').css('opacity', '1') + .parent().find('li.nomouse').show() + .find('input').prop('readonly', false) + .parents('ul') + .find('.w2ui-list-remove').show(); + }, 1); + } + + // clean + div.find('.w2ui-enum-placeholder').remove(); + ul.find('li').not('li.nomouse').remove(); + // add new list + if (html !== '') { + ul.prepend(html); + } else if ($(obj.el).attr('placeholder') != null && div.find('input').val() === '') { + var style = + 'padding-top: ' + $(this.el).css('padding-top') + ';'+ + 'padding-left: ' + $(this.el).css('padding-left') + '; ' + + 'box-sizing: ' + $(this.el).css('box-sizing') + '; ' + + 'line-height: ' + $(this.el).css('line-height') + '; ' + + 'font-size: ' + $(this.el).css('font-size') + '; ' + + 'font-family: ' + $(this.el).css('font-family') + '; '; + div.prepend('
    '+ $(obj.el).attr('placeholder') +'
    '); + } + // ITEMS events + div.off('scroll.w2field').on('scroll.w2field', function (event) { + var edata = obj.trigger({ phase: 'before', type: 'scroll', target: obj.el, originalEvent: event }); + if (edata.isCancelled === true) return; + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }) + .find('li') + .data('mouse', 'out') + .on('click', function (event) { + var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI')); + var item = selected[$(target).attr('index')]; + if ($(target).hasClass('nomouse')) return; + event.stopPropagation(); + // default behavior + if ($(event.target).hasClass('w2ui-list-remove')) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (edata.isCancelled === true) return; + // default behavior + $().w2overlay(); + selected.splice($(event.target).attr('index'), 1); + $(obj.el).trigger('change'); + $(event.target).parent().fadeOut('fast'); + setTimeout(function () { + obj.refresh(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, 300); + } else { + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'click', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (edata.isCancelled === true) return; + // if file - show image preview + if (obj.type == 'file') { + var preview = ''; + if ((/image/i).test(item.type)) { // image + preview = '
    '+ + ' '+ + '
    '; + } + var td1 = 'style="padding: 3px; text-align: right; color: #777;"'; + var td2 = 'style="padding: 3px"'; + preview += '
    '+ + ' '+ + ' '+ + ' '+ + ' '+ + ' '+ + '
    '+ w2utils.lang('Name') +':'+ item.name +'
    '+ w2utils.lang('Size') +':'+ w2utils.formatSize(item.size) +'
    '+ w2utils.lang('Type') +':' + + ' '+ item.type +''+ + '
    '+ w2utils.lang('Modified') +':'+ w2utils.date(item.modified) +'
    '+ + '
    '; + $('#w2ui-overlay').remove(); + $(target).w2overlay(preview); + } // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + }) + .on('mouseover', function (event) { + var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI')); + if ($(target).hasClass('nomouse')) return; + if ($(target).data('mouse') == 'out') { + var item = selected[$(event.target).attr('index')]; + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'mouseOver', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (edata.isCancelled === true) return; + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + $(target).data('mouse', 'over'); + }) + .on('mouseout', function (event) { + var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI')); + if ($(target).hasClass('nomouse')) return; + $(target).data('mouse', 'leaving'); + setTimeout(function () { + if ($(target).data('mouse') == 'leaving') { + $(target).data('mouse', 'out'); + var item = selected[$(event.target).attr('index')]; + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'mouseOut', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (edata.isCancelled === true) return; + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + }, 0); + }); + // adjust height + $(this.el).height('auto'); + var cntHeight = $(div).find('> div.w2ui-multi-items').height() + w2utils.getSize(div, '+height') * 2; + if (cntHeight < 26) cntHeight = 26; + if (cntHeight > options.maxHeight) cntHeight = options.maxHeight; + if (div.length > 0) div[0].scrollTop = 1000; + var inpHeight = w2utils.getSize($(this.el), 'height') - 2; + if (inpHeight > cntHeight) cntHeight = inpHeight; + $(div).css({ 'height': cntHeight + 'px', overflow: (cntHeight == options.maxHeight ? 'auto' : 'hidden') }); + if (cntHeight < options.maxHeight) $(div).prop('scrollTop', 0); + $(this.el).css({ 'height' : (cntHeight + 2) + 'px' }); + // update size + if (obj.type == 'enum') { + var tmp = obj.helpers.multi.find('input'); + tmp.width(((tmp.val().length + 2) * 8) + 'px'); + } + } + return (new Date()).getTime() - time; + }, + + reset: function () { + var type = this.type; + this.clear(); + this.type = type; + this.init(); + }, + + // resizing width of list, enum, file controls + resize: function () { + var obj = this; + var new_width = $(obj.el).width(); + var new_height = $(obj.el).height(); + if (obj.tmp.current_width == new_width && new_height > 0) return; + + var focus = this.helpers.focus; + var multi = this.helpers.multi; + var suffix = this.helpers.suffix; + var prefix = this.helpers.prefix; + + // resize helpers + if (focus) { + focus.width($(obj.el).width()); + } + if (multi) { + var width = (w2utils.getSize(obj.el, 'width') + - parseInt($(obj.el).css('margin-left'), 10) + - parseInt($(obj.el).css('margin-right'), 10)); + $(multi).width(width); + } + if (suffix) { + obj.options.suffix = '
    '; + obj.addSuffix(); + } + if (prefix) { + obj.addPrefix(); + } + // remember width + obj.tmp.current_width = new_width; + }, + + clean: function (val) { + //issue #499 + if(typeof val == 'number'){ + return val; + } + var options = this.options; + val = String(val).trim(); + // clean + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { + if (typeof val == 'string') { + if (options.autoFormat && ['money', 'currency'].indexOf(this.type) != -1) val = String(val).replace(options.moneyRE, ''); + if (options.autoFormat && this.type == 'percent') val = String(val).replace(options.percentRE, ''); + if (options.autoFormat && ['int', 'float'].indexOf(this.type) != -1) val = String(val).replace(options.numberRE, ''); + val = val.replace(/\s+/g, '').replace(w2utils.settings.groupSymbol, '').replace(w2utils.settings.decimalSymbol, '.'); + } + if (parseFloat(val) == val) { + if (options.min != null && val < options.min) { val = options.min; $(this.el).val(options.min); } + if (options.max != null && val > options.max) { val = options.max; $(this.el).val(options.max); } + } + if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = ''; + } + return val; + }, + + format: function (val) { + var options = this.options; + // autoformat numbers or money + if (options.autoFormat && val !== '') { + switch (this.type) { + case 'money': + case 'currency': + val = w2utils.formatNumber(val, options.currencyPrecision, options.groupSymbol); + if (val !== '') val = options.currencyPrefix + val + options.currencySuffix; + break; + case 'percent': + val = w2utils.formatNumber(val, options.precision, options.groupSymbol); + if (val !== '') val += '%'; + break; + case 'float': + val = w2utils.formatNumber(val, options.precision, options.groupSymbol); + break; + case 'int': + val = w2utils.formatNumber(val, 0, options.groupSymbol); + break; + } + } + return val; + }, + + change: function (event) { + var obj = this; + var options = obj.options; + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { + // check max/min + var val = $(this.el).val(); + var new_val = this.format(this.clean($(this.el).val())); + // if was modified + if (val !== '' && val != new_val) { + $(this.el).val(new_val).change(); + // cancel event + event.stopPropagation(); + event.preventDefault(); + return false; + } + } + // color + if (this.type == 'color') { + var color = '#' + $(this.el).val(); + if ($(this.el).val().length != 6 && $(this.el).val().length != 3) color = ''; + $(this.el).next().find('div').css('background-color', color); + if ($(obj.el).is(':focus')) this.updateOverlay(); + } + // list, enum + if (['list', 'enum', 'file'].indexOf(this.type) != -1) { + obj.refresh(); + // need time out to show icon indent properly + setTimeout(function () { obj.refresh(); }, 5); + } + // date, time + if (['date', 'time', 'datetime'].indexOf(this.type) != -1) { + // convert linux timestamps + var tmp = parseInt(obj.el.value); + if (w2utils.isInt(obj.el.value) && tmp > 3000) { + if (this.type == 'time') $(obj.el).val(w2utils.formatTime(new Date(tmp), options.format)).change(); + if (this.type == 'date') $(obj.el).val(w2utils.formatDate(new Date(tmp), options.format)).change(); + if (this.type == 'datetime') $(obj.el).val(w2utils.formatDateTime(new Date(tmp), options.format)).change(); + } + } + }, + + click: function (event) { + event.stopPropagation(); + // lists + if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { + if (!$(this.el).is(':focus')) this.focus(event); + } + // other fields with drops + if (['date', 'time', 'color', 'datetime'].indexOf(this.type) != -1) { + this.updateOverlay(); + } + }, + + focus: function (event) { + var obj = this; + var options = this.options; + // color, date, time + if (['color', 'date', 'time', 'datetime'].indexOf(obj.type) !== -1) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + setTimeout(function () { obj.updateOverlay(); }, 150); + } + // menu + if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + obj.resize(); + setTimeout(function () { + if (obj.type == 'list' && $(obj.el).is(':focus')) { + $(obj.helpers.focus).find('input').focus(); + return; + } + obj.search(); + setTimeout(function () { obj.updateOverlay(); }, 1); + }, 1); + } + // file + if (obj.type == 'file') { + $(obj.helpers.multi).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); + } + }, + + blur: function (event) { + var obj = this; + var options = obj.options; + var val = $(obj.el).val().trim(); + // hide overlay + if (['color', 'date', 'time', 'list', 'combo', 'enum', 'datetime'].indexOf(obj.type) != -1) { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + } + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { + if (val !== '' && !obj.checkType(val)) { + $(obj.el).val('').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid number'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + } + // date or time + if (['date', 'time', 'datetime'].indexOf(obj.type) != -1) { + // check if in range + if (val !== '' && !obj.inRange(obj.el.value)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not in range'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } else { + if (obj.type == 'date' && val !== '' && !w2utils.isDate(obj.el.value, options.format)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid date'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + else if (obj.type == 'time' && val !== '' && !w2utils.isTime(obj.el.value)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid time'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + else if (obj.type == 'datetime' && val !== '' && !w2utils.isDateTime(obj.el.value, options.format)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid date'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + } + } + // clear search input + if (obj.type == 'enum') { + $(obj.helpers.multi).find('input').val('').width(20); + } + // file + if (obj.type == 'file') { + $(obj.helpers.multi).css({ 'outline': 'none' }); + } + }, + + keyPress: function (event) { + var obj = this; + var options = obj.options; + // ignore wrong pressed key + if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'bin', 'color', 'alphanumeric'].indexOf(obj.type) != -1) { + // keyCode & charCode differ in FireFox + if (event.metaKey || event.ctrlKey || event.altKey || (event.charCode != event.keyCode && event.keyCode > 0)) return; + var ch = String.fromCharCode(event.charCode); + if (!obj.checkType(ch, true) && event.keyCode != 13) { + event.preventDefault(); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + return false; + } + } + // update date popup + if (['date', 'time', 'datetime'].indexOf(obj.type) != -1) { + if (event.keyCode !== 9) setTimeout(function () { obj.updateOverlay(); }, 1); + } + }, + + keyDown: function (event, extra) { + var obj = this; + var options = obj.options; + var key = event.keyCode || (extra && extra.keyCode); + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { + if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + var cancel = false; + var val = parseFloat($(obj.el).val().replace(options.moneyRE, '')) || 0; + var inc = options.step; + if (event.ctrlKey || event.metaKey) inc = 10; + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + $(obj.el).val((val + inc <= options.max || options.max == null ? Number((val + inc).toFixed(12)) : options.max)).change(); + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + $(obj.el).val((val - inc >= options.min || options.min == null ? Number((val - inc).toFixed(12)) : options.min)).change(); + cancel = true; + break; + } + if (cancel) { + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + }, 0); + } + } + // date + if (obj.type == 'date') { + if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + var cancel = false; + var daymil = 24*60*60*1000; + var inc = 1; + if (event.ctrlKey || event.metaKey) inc = 10; + var dt = w2utils.isDate($(obj.el).val(), options.format, true); + if (!dt) { dt = new Date(); daymil = 0; } + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + var newDT = w2utils.formatDate(dt.getTime() + daymil, options.format); + if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format); + $(obj.el).val(newDT).change(); + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + var newDT = w2utils.formatDate(dt.getTime() - daymil, options.format); + if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format); + $(obj.el).val(newDT).change(); + cancel = true; + break; + } + if (cancel) { + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + obj.updateOverlay(); + }, 0); + } + } + // time + if (obj.type == 'time') { + if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + var cancel = false; + var inc = (event.ctrlKey || event.metaKey ? 60 : 1); + var val = $(obj.el).val(); + var time = obj.toMin(val) || obj.toMin((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1)); + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + time += inc; + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + time -= inc; + cancel = true; + break; + } + if (cancel) { + $(obj.el).val(obj.fromMin(time)).change(); + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + }, 0); + } + } + // datetime + if (obj.type == 'datetime') { + if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + var cancel = false; + var daymil = 24*60*60*1000; + var inc = 1; + if (event.ctrlKey || event.metaKey) inc = 10; + var str = $(obj.el).val(); + var dt = w2utils.isDateTime(str, this.options.format, true); + if (!dt) { dt = new Date(); daymil = 0; } + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + var newDT = w2utils.formatDateTime(dt.getTime() + daymil, options.format); + if (inc == 10) newDT = w2utils.formatDateTime(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format); + $(obj.el).val(newDT).change(); + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + var newDT = w2utils.formatDateTime(dt.getTime() - daymil, options.format); + if (inc == 10) newDT = w2utils.formatDateTime(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format); + $(obj.el).val(newDT).change(); + cancel = true; + break; + } + if (cancel) { + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + obj.updateOverlay(); + }, 0); + } + } + // color + if (obj.type == 'color') { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + // paste + if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { + $(obj.el).prop('maxlength', 7); + setTimeout(function () { + var val = $(obj).val(); + if (val.substr(0, 1) == '#') val = val.substr(1); + if (!w2utils.isHex(val)) val = ''; + $(obj).val(val).prop('maxlength', 6).change(); + }, 20); + } + if ((event.ctrlKey || event.metaKey) && !event.shiftKey) { + var dir = null; + var newColor = null; + switch (key) { + case 38: // up + dir = 'up'; + break; + case 40: // down + dir = 'down'; + break; + case 39: // right + dir = 'right'; + break; + case 37: // left + dir = 'left'; + break; + } + if (obj.el.nav && dir != null) { + newColor = obj.el.nav(dir); + $(obj.el).val(newColor).change(); + event.preventDefault(); + } + } + } + // list/select/combo + if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + var selected = $(obj.el).data('selected'); + var focus = $(obj.el); + var indexOnly = false; + if (['list', 'enum'].indexOf(obj.type) != -1) { + if (obj.type == 'list') { + focus = $(obj.helpers.focus).find('input'); + } + if (obj.type == 'enum') { + focus = $(obj.helpers.multi).find('input'); + } + // not arrows - refresh + if ([37, 38, 39, 40].indexOf(key) == -1) { + setTimeout(function () { obj.refresh(); }, 1); + } + // paste + if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { + setTimeout(function () { + obj.refresh(); + obj.search(); + obj.request(); + }, 50); + } + } + // apply arrows + switch (key) { + case 27: // escape + if (obj.type == 'list') { + if (focus.val() !== '') focus.val(''); + event.stopPropagation(); // escape in field should not close popup + } + break; + case 37: // left + case 39: // right + // indexOnly = true; + break; + case 13: // enter + if ($('#w2ui-overlay').length === 0) break; // no action if overlay not open + var item = options.items[options.index]; + if (obj.type == 'enum') { + if (item != null) { + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (edata.isCancelled === true) return; + item = edata.item; // need to reassign because it could be recreated by user + // default behavior + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete item.hidden; + delete obj.tmp.force_open; + selected.push(item); + $(obj.el).change(); + focus.val('').width(20); + obj.refresh(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } else { + // trigger event + item = { id: focus.val(), text: focus.val() }; + var edata = obj.trigger({ phase: 'before', type: 'new', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (edata.isCancelled === true) return; + item = edata.item; // need to reassign because it could be recreated by user + // default behavior + if (typeof obj.onNew == 'function') { + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete obj.tmp.force_open; + selected.push(item); + $(obj.el).change(); + focus.val('').width(20); + obj.refresh(); + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + } else { + if (item) $(obj.el).data('selected', item).val(item.text).change(); + if ($(obj.el).val() === '' && $(obj.el).data('selected')) $(obj.el).removeData('selected').val('').change(); + if (obj.type == 'list') { + focus.val(''); + obj.refresh(); + } + // hide overlay + obj.tmp.force_hide = true; + } + break; + case 8: // backspace + case 46: // delete + if (obj.type == 'enum' && key == 8) { + if (focus.val() === '' && selected.length > 0) { + var item = selected[selected.length - 1]; + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (edata.isCancelled === true) return; + // default behavior + selected.pop(); + $(obj.el).trigger('change'); + obj.refresh(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + } + if (obj.type == 'list' && focus.val() === '') { + $(obj.el).data('selected', {}).change(); + obj.refresh(); + } + break; + case 38: // up + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index--; + while (options.index > 0 && options.items[options.index].hidden) options.index--; + if (options.index === 0 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } + indexOnly = true; + break; + case 40: // down + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : -1; + options.index++; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (options.index == options.items.length-1 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index--; + } + // show overlay if not shown + if (focus.val() === '' && $('#w2ui-overlay').length === 0) { + obj.tmp.force_open = true; + } else { + indexOnly = true; + } + break; + } + if (indexOnly) { + if (options.index < 0) options.index = 0; + if (options.index >= options.items.length) options.index = options.items.length -1; + obj.updateOverlay(indexOnly); + // cancel event + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + if (obj.type == 'enum') { + var tmp = focus.get(0); + tmp.setSelectionRange(tmp.value.length, tmp.value.length); + } else if (obj.type == 'list') { + var tmp = focus.get(0); + tmp.setSelectionRange(tmp.value.length, tmp.value.length); + } else { + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + } + }, 0); + return; + } + // expand input + if (obj.type == 'enum') { + focus.width(((focus.val().length + 2) * 8) + 'px'); + } + } + }, + + keyUp: function (event) { + var obj = this; + if (this.type == 'color') { + if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { + $(this).prop('maxlength', 6); + } + } + if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + // need to be here for ipad compa + if ([16, 17, 18, 20, 37, 39, 91].indexOf(event.keyCode) == -1) { // no refreah on crtl, shift, left/right arrows, etc + var input = $(this.helpers.focus).find('input'); + if (input.length === 0) input = $(this.el); // for combo list + // trigger event + var edata = this.trigger({ phase: 'before', type: 'search', originalEvent: event, target: input, search: input.val() }); + if (edata.isCancelled === true) return; + // regular + if (!this.tmp.force_hide) this.request(); + if (input.val().length == 1) this.refresh(); + if ($('#w2ui-overlay').length === 0 || [38, 40].indexOf(event.keyCode) == -1) { // no search on arrows + this.search(); + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + } + }, + + clearCache: function () { + var options = this.options; + options.items = []; + this.tmp.xhr_loading = false; + this.tmp.xhr_search = ''; + this.tmp.xhr_total = -1; + }, + + request: function (interval) { + var obj = this; + var options = this.options; + var search = $(obj.el).val() || ''; + // if no url - do nothing + if (!options.url) return; + // -- + if (obj.type == 'enum') { + var tmp = $(obj.helpers.multi).find('input'); + if (tmp.length === 0) search = ''; else search = tmp.val(); + } + if (obj.type == 'list') { + var tmp = $(obj.helpers.focus).find('input'); + if (tmp.length === 0) search = ''; else search = tmp.val(); + } + if (options.minLength !== 0 && search.length < options.minLength) { + options.items = []; // need to empty the list + this.updateOverlay(); + return; + } + if (interval == null) interval = options.interval; + if (obj.tmp.xhr_search == null) obj.tmp.xhr_search = ''; + if (obj.tmp.xhr_total == null) obj.tmp.xhr_total = -1; + // check if need to search + if (options.url && $(obj.el).prop('readonly') !== true && $(obj.el).prop('disabled') !== true && ( + (options.items.length === 0 && obj.tmp.xhr_total !== 0) || + (obj.tmp.xhr_total == options.cacheMax && search.length > obj.tmp.xhr_search.length) || + (search.length >= obj.tmp.xhr_search.length && search.substr(0, obj.tmp.xhr_search.length) != obj.tmp.xhr_search) || + (search.length < obj.tmp.xhr_search.length) + )) { + // empty list + if (obj.tmp.xhr) obj.tmp.xhr.abort(); + obj.tmp.xhr_loading = true; + obj.search(); + // timeout + clearTimeout(obj.tmp.timeout); + obj.tmp.timeout = setTimeout(function () { + // trigger event + var url = options.url; + var postData = { + search : search, + max : options.cacheMax + }; + $.extend(postData, options.postData); + var edata = obj.trigger({ phase: 'before', type: 'request', search: search, target: obj.el, url: url, postData: postData }); + if (edata.isCancelled === true) return; + url = edata.url; + postData = edata.postData; + var ajaxOptions = { + type : 'GET', + url : url, + data : postData, + dataType : 'JSON' // expected from server + }; + if (options.method) ajaxOptions.type = options.method; + if (w2utils.settings.dataType == 'JSON') { + ajaxOptions.type = 'POST'; + ajaxOptions.data = JSON.stringify(ajaxOptions.data); + ajaxOptions.contentType = 'application/json'; + } + if (w2utils.settings.dataType == 'HTTPJSON') { + ajaxOptions.data = { request: JSON.stringify(ajaxOptions.data) }; + } + if (options.method != null) ajaxOptions.type = options.method; + obj.tmp.xhr = $.ajax(ajaxOptions) + .done(function (data, status, xhr) { + // trigger event + var edata2 = obj.trigger({ phase: 'before', type: 'load', target: obj.el, search: postData.search, data: data, xhr: xhr }); + if (edata2.isCancelled === true) return; + // default behavior + data = edata2.data; + if (typeof data == 'string') data = JSON.parse(data); + if (data.records == null && data.items != null) { + // needed for backward compatibility + data.records = data.items; + delete data.items; + } + if (data.status != 'success' || !Array.isArray(data.records)) { + console.log('ERROR: server did not return proper structure. It should return', { status: 'success', records: [{ id: 1, text: 'item' }] }); + return; + } + // remove all extra items if more then needed for cache + if (data.records.length > options.cacheMax) data.records.splice(options.cacheMax, 100000); + // map id and text + if (options.recId == null && options.recid != null) options.recId = options.recid; // since lower-case recid is used in grid + if (options.recId || options.recText) { + data.records.forEach(function (item) { + if (typeof options.recId == 'string') item.id = item[options.recId]; + if (typeof options.recId == 'function') item.id = options.recId(item); + if (typeof options.recText == 'string') item.text = item[options.recText]; + if (typeof options.recText == 'function') item.text = options.recText(item); + }); + } + // remember stats + obj.tmp.xhr_loading = false; + obj.tmp.xhr_search = search; + obj.tmp.xhr_total = data.records.length; + options.items = obj.normMenu(data.records); + if (search === '' && data.records.length === 0) obj.tmp.emptySet = true; else obj.tmp.emptySet = false; + obj.search(); + // event after + obj.trigger($.extend(edata2, { phase: 'after' })); + }) + .fail(function (xhr, status, error) { + // trigger event + var errorObj = { status: status, error: error, rawResponseText: xhr.responseText }; + var edata2 = obj.trigger({ phase: 'before', type: 'error', target: obj.el, search: search, error: errorObj, xhr: xhr }); + if (edata2.isCancelled === true) return; + // default behavior + if (status != 'abort') { + var data; + try { data = $.parseJSON(xhr.responseText); } catch (e) {} + console.log('ERROR: Server communication failed.', + '\n EXPECTED:', { status: 'success', records: [{ id: 1, text: 'item' }] }, + '\n OR:', { status: 'error', message: 'error message' }, + '\n RECEIVED:', typeof data == 'object' ? data : xhr.responseText); + } + // reset stats + obj.clearCache(); + obj.search(); + // event after + obj.trigger($.extend(edata2, { phase: 'after' })); + }); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, interval); + } + }, + + search: function () { + var obj = this; + var options = this.options; + var search = $(obj.el).val(); + var target = obj.el; + var ids = []; + var selected = $(obj.el).data('selected'); + if (obj.type == 'enum') { + target = $(obj.helpers.multi).find('input'); + search = target.val(); + for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } + } + else if (obj.type == 'list') { + target = $(obj.helpers.focus).find('input'); + search = target.val(); + for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } + } + if (obj.tmp.xhr_loading !== true) { + var shown = 0; + for (var i = 0; i < options.items.length; i++) { + var item = options.items[i]; + if (options.compare != null) { + if (typeof options.compare == 'function') { + item.hidden = (options.compare.call(this, item, search) === false ? true : false); + } + } else { + var prefix = ''; + var suffix = ''; + if (['is', 'begins'].indexOf(options.match) != -1) prefix = '^'; + if (['is', 'ends'].indexOf(options.match) != -1) suffix = '$'; + try { + var re = new RegExp(prefix + search + suffix, 'i'); + if (re.test(item.text) || item.text == '...') item.hidden = false; else item.hidden = true; + } catch (e) {} + } + if (options.filter === false) item.hidden = false; + // do not show selected items + if (obj.type == 'enum' && $.inArray(item.id, ids) != -1) item.hidden = true; + if (item.hidden !== true) { shown++; delete item.hidden; } + } + // preselect first item + options.index = -1; + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + if (shown <= 0) options.index = -1; + options.spinner = false; + obj.updateOverlay(); + setTimeout(function () { + var html = $('#w2ui-overlay').html() || ''; + if (options.markSearch && html.indexOf('$.fn.w2menuHandler') != -1) { // do not highlight when no items + $('#w2ui-overlay').w2marker(search); + } + }, 1); + } else { + options.items.splice(0, options.cacheMax); + options.spinner = true; + obj.updateOverlay(); + } + }, + + updateOverlay: function (indexOnly) { + var obj = this; + var options = this.options; + // color + if (this.type == 'color') { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + $(this.el).w2color({ color: $(this.el).val(), transparent: options.transparent }, function (color) { + if (color == null) return; + $(obj.el).val(color).change(); + }); + } + // date + if (this.type == 'date') { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + if ($('#w2ui-overlay').length === 0) { + $(obj.el).w2overlay('
    ', { + css: { "background-color": "#f5f5f5" } + }); + } + var month, year; + var dt = w2utils.isDate($(obj.el).val(), obj.options.format, true); + if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); } + (function refreshCalendar(month, year) { + $('#w2ui-overlay > div > div').html(obj.getMonthHTML(month, year, $(obj.el).val())); + $('#w2ui-overlay .w2ui-calendar-title') + .on('mousedown', function () { + if ($(this).next().hasClass('w2ui-calendar-jump')) { + $(this).next().remove(); + } else { + var selYear, selMonth; + $(this).after('
    '); + $(this).next().hide().html(obj.getYearHTML()).fadeIn(200); + setTimeout(function () { + $('#w2ui-overlay .w2ui-calendar-jump') + .find('.w2ui-jump-month, .w2ui-jump-year') + .on('click', function () { + if ($(this).hasClass('w2ui-jump-month')) { + $(this).parent().find('.w2ui-jump-month').removeClass('selected'); + $(this).addClass('selected'); + selMonth = $(this).attr('name'); + } + if ($(this).hasClass('w2ui-jump-year')) { + $(this).parent().find('.w2ui-jump-year').removeClass('selected'); + $(this).addClass('selected'); + selYear = $(this).attr('name'); + } + if (selYear != null && selMonth != null) { + $('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100); + setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100); + } + }); + $('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000); + }, 1); + } + }); + $('#w2ui-overlay .w2ui-date') + .on('mousedown', function () { + var day = $(this).attr('date'); + $(obj.el).val(day).change(); + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + }) + .on('mouseup', function () { + setTimeout(function () { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); + }, 10); + }); + $('#w2ui-overlay .previous').on('mousedown', function () { + var tmp = obj.options.current.split('/'); + tmp[0] = parseInt(tmp[0]) - 1; + refreshCalendar(tmp[0], tmp[1]); + }); + $('#w2ui-overlay .next').on('mousedown', function () { + var tmp = obj.options.current.split('/'); + tmp[0] = parseInt(tmp[0]) + 1; + refreshCalendar(tmp[0], tmp[1]); + }); + }) (month, year); + } + // time + if (this.type == 'time') { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + if ($('#w2ui-overlay').length === 0) { + $(obj.el).w2overlay('
    ', { + css: { "background-color": "#fff" } + }); + } + var h24 = (this.options.format == 'h24'); + $('#w2ui-overlay > div').html(obj.getHourHTML()); + $('#w2ui-overlay .w2ui-time') + .on('mousedown', function (event) { + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + var hour = $(this).attr('hour'); + $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); + }); + if (this.options.noMinutes == null || this.options.noMinutes === false) { + $('#w2ui-overlay .w2ui-time') + .on('mouseup', function () { + var hour = $(this).attr('hour'); + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + $(obj.el).w2overlay('
    ', { css: { "background-color": "#fff" } }); + $('#w2ui-overlay > div').html(obj.getMinHTML(hour)); + $('#w2ui-overlay .w2ui-time') + .on('mousedown', function () { + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + var min = $(this).attr('min'); + $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); + }) + .on('mouseup', function () { + setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); + }); + }); + } else { + $('#w2ui-overlay .w2ui-time') + .on('mouseup', function () { + setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); + }); + } + } + // datetime + if (this.type == 'datetime') { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + // hide overlay if we are in the time selection + if ($("#w2ui-overlay .w2ui-time").length > 0) $('#w2ui-overlay')[0].hide(); + if ($('#w2ui-overlay').length === 0) { + $(obj.el).w2overlay('
    ', { + css: { "background-color": "#f5f5f5" } + }); + } + var month, year; + var dt = w2utils.isDateTime($(obj.el).val(), obj.options.format, true); + if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); } + var selDate = null; + (function refreshCalendar(month, year) { + $('#w2ui-overlay > div > div').html( + obj.getMonthHTML(month, year, $(obj.el).val()) + + (options.btn_now ? '
    '+ w2utils.lang('Current Date & Time') + '
    ' : '') + ); + $('#w2ui-overlay .w2ui-calendar-title') + .on('mousedown', function () { + if ($(this).next().hasClass('w2ui-calendar-jump')) { + $(this).next().remove(); + } else { + var selYear, selMonth; + $(this).after('
    '); + $(this).next().hide().html(obj.getYearHTML()).fadeIn(200); + setTimeout(function () { + $('#w2ui-overlay .w2ui-calendar-jump') + .find('.w2ui-jump-month, .w2ui-jump-year') + .on('click', function () { + if ($(this).hasClass('w2ui-jump-month')) { + $(this).parent().find('.w2ui-jump-month').removeClass('selected'); + $(this).addClass('selected'); + selMonth = $(this).attr('name'); + } + if ($(this).hasClass('w2ui-jump-year')) { + $(this).parent().find('.w2ui-jump-year').removeClass('selected'); + $(this).addClass('selected'); + selYear = $(this).attr('name'); + } + if (selYear != null && selMonth != null) { + $('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100); + setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100); + } + }); + $('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000); + }, 1); + } + }); + $('#w2ui-overlay .w2ui-date') + .on('mousedown', function () { + var day = $(this).attr('date'); + $(obj.el).val(day).change(); + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + selDate = new Date($(this).attr('data-date')); + }) + .on('mouseup', function () { + // continue with time picker + var selHour, selMin; + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + $(obj.el).w2overlay('
    ', { css: { "background-color": "#fff" } }); + var h24 = (obj.options.format == 'h24'); + $('#w2ui-overlay > div').html(obj.getHourHTML()); + $('#w2ui-overlay .w2ui-time') + .on('mousedown', function (event) { + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + selHour = $(this).attr('hour'); + selDate.setHours(selHour); + var txt = w2utils.formatDateTime(selDate, obj.options.format); + $(obj.el).val(txt).change(); + //$(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); + }); + if (obj.options.noMinutes == null || obj.options.noMinutes === false) { + $('#w2ui-overlay .w2ui-time') + .on('mouseup', function () { + var hour = $(this).attr('hour'); + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + $(obj.el).w2overlay('
    ', { css: { "background-color": "#fff" } }); + $('#w2ui-overlay > div').html(obj.getMinHTML(hour)); + $('#w2ui-overlay .w2ui-time') + .on('mousedown', function () { + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + selMin = $(this).attr('min'); + selDate.setHours(selHour, selMin); + var txt = w2utils.formatDateTime(selDate, obj.options.format); + $(obj.el).val(txt).change(); + //$(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); + }) + .on('mouseup', function () { + setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); + }); + }); + } else { + $('#w2ui-overlay .w2ui-time') + .on('mouseup', function () { + setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); + }); + } + }); + $('#w2ui-overlay .previous').on('mousedown', function () { + var tmp = obj.options.current.split('/'); + tmp[0] = parseInt(tmp[0]) - 1; + refreshCalendar(tmp[0], tmp[1]); + }); + $('#w2ui-overlay .next').on('mousedown', function () { + var tmp = obj.options.current.split('/'); + tmp[0] = parseInt(tmp[0]) + 1; + refreshCalendar(tmp[0], tmp[1]); + }); + // "now" button + $('#w2ui-overlay .now') + .on('mousedown', function () { + // this currently ignores blocked days or start / end dates! + var tmp = w2utils.formatDateTime(new Date(), obj.options.format); + $(obj.el).val(tmp).change(); + return false; + }) + .on('mouseup', function () { + setTimeout(function () { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); + }, 10); + }); + }) (month, year); + } + // list + if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { + var el = this.el; + var input = this.el; + if (this.type == 'enum') { + el = $(this.helpers.multi); + input = $(el).find('input'); + } + if (this.type == 'list') { + var sel = $(input).data('selected'); + if ($.isPlainObject(sel) && !$.isEmptyObject(sel) && options.index == -1) { + options.items.forEach(function (item, ind) { + if (item.id == sel.id) { + options.index = ind; + } + }); + } + input = $(this.helpers.focus).find('input'); + } + if ($(input).is(':focus')) { + if (options.openOnFocus === false && $(input).val() === '' && obj.tmp.force_open !== true) { + $().w2overlay(); + return; + } + if (obj.tmp.force_hide) { + $().w2overlay(); + setTimeout(function () { + delete obj.tmp.force_hide; + }, 1); + return; + } + if ($(input).val() !== '') delete obj.tmp.force_open; + var msgNoItems = w2utils.lang('No matches'); + if (options.url != null && $(input).val().length < options.minLength && obj.tmp.emptySet !== true) msgNoItems = options.minLength + ' ' + w2utils.lang('letters or more...'); + if (options.url != null && $(input).val() === '' && obj.tmp.emptySet !== true) msgNoItems = w2utils.lang('Type to search...'); + if (options.url == null && options.items.length === 0) msgNoItems = w2utils.lang('Empty list'); + if (options.msgNoItems != null) msgNoItems = options.msgNoItems; + if (msgNoItems == 'function') msgNoItems = msgNoItems(options); + $(el).w2menu((!indexOnly ? 'refresh' : 'refresh-index'), $.extend(true, {}, options, { + search : false, + render : options.renderDrop, + maxHeight : options.maxDropHeight, + maxWidth : options.maxDropWidth, + msgNoItems : msgNoItems, + // selected with mouse + onSelect: function (event) { + if (obj.type == 'enum') { + var selected = $(obj.el).data('selected'); + if (event.item) { + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: event.item }); + if (edata.isCancelled === true) return; + // default behavior + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete event.item.hidden; + selected.push(event.item); + $(obj.el).data('selected', selected).change(); + $(obj.helpers.multi).find('input').val('').width(20); + obj.refresh(); + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + } else { + $(obj.el).data('selected', event.item).val(event.item.text).change(); + if (obj.helpers.focus) obj.helpers.focus.find('input').val(''); + } + } + })); + } + } + }, + + inRange: function (str, onlyDate) { + var inRange = false; + if (this.type == 'date') { + var dt = w2utils.isDate(str, this.options.format, true); + if (dt) { + // enable range + if (this.options.start || this.options.end) { + var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val()); + var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val()); + var start = w2utils.isDate(st, this.options.format, true); + var end = w2utils.isDate(en, this.options.format, true); + var current = new Date(dt); + if (!start) start = current; + if (!end) end = current; + if (current >= start && current <= end) inRange = true; + } else { + inRange = true; + } + // block predefined dates + if (this.options.blocked && $.inArray(str, this.options.blocked) != -1) inRange = false; + + /* + clockWeekDay - type: array or integers. every element - number of week day. + number of weekday (1 - monday, 2 - tuesday, 3 - wensday, 4 - thursday, 5 - friday, 6 - saturday, 0 - sunday) + for block in calendar (for example, block all sundays so user can't choose sunday in calendar) + */ + if (this.options.blockWeekDays != null && this.options.blockWeekDays != undefined + && this.options.blockWeekDays.length != undefined){ + var l = this.options.blockWeekDays.length; + for (var i=0; i= tm1 && tm <= tm2) inRange = true; + } else { + inRange = true; + } + } else if (this.type == 'datetime') { + var dt = w2utils.isDateTime(str, this.options.format, true); + if (dt) { + // enable range + if (this.options.start || this.options.end) { + var start, end; + if (typeof this.options.start == 'object' && this.options.start instanceof Date) { + start = this.options.start; + } else { + var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val()); + if (st.trim() !== '') { + start = w2utils.isDateTime(st, this.options.format, true); + } else { + start = ''; + } + } + if (typeof this.options.end == 'object' && this.options.end instanceof Date) { + end = this.options.end; + } else { + var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val()); + if (en.trim() !== '') { + end = w2utils.isDateTime(en, this.options.format, true); + } else { + end = ''; + } + } + var current = dt; // new Date(dt); + if (!start) start = current; + if (!end) end = current; + if (onlyDate && start instanceof Date) { + start.setHours(0); + start.setMinutes(0); + start.setSeconds(0); + } + if (current >= start && current <= end) inRange = true; + } else { + inRange = true; + } + // block predefined dates + if (inRange && this.options.blocked) { + for (var i=0; i'+ + obj.options.prefix + + '' + ); + 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( + '
     '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '); + var height = w2utils.getSize(obj.el, 'height'); + 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 = $(obj.el).attr('tabIndex'); + if (tabIndex && tabIndex != -1) obj.el._tabIndex = tabIndex; + if (obj.el._tabIndex) tabIndex = obj.el._tabIndex; + if (tabIndex == null) tabIndex = -1; + // 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 (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 = -1; + + 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.on('click', function (event) { + $(obj.el).focus(); + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + obj.blur(event); + obj.resize(); + setTimeout(function () { div.find('input').click(); }, 10); // needed this when clicked on items div + }) + .on('dragenter', function (event) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + $(div).addClass('w2ui-file-dragover'); + }) + .on('dragleave', function (event) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + var tmp = $(event.target).parents('.w2ui-field-helper'); + if (tmp.length === 0) $(div).removeClass('w2ui-file-dragover'); + }) + .on('drop', 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]); + // cancel to stop browser behaviour + event.preventDefault(); + event.stopPropagation(); + }) + .on('dragover', function (event) { + // cancel to stop browser behaviour + event.preventDefault(); + event.stopPropagation(); + }); + div.find('input') + .on('click', function (event) { + event.stopPropagation(); + }) + .on('change', function () { + 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 = 'Maximum total size is '+ w2utils.formatSize(options.maxSize); + if (options.silent === false) $(obj.el).w2tag(err); + console.log('ERROR: '+ err); + return; + } + if (options.max !== 0 && cnt >= options.max) { + err = 'Maximum number of files is '+ options.max; + if (options.silent === false) $(obj.el).w2tag(err); + 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('change'); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }; + })(); + reader.readAsDataURL(file); + } else { + obj.refresh(); + $(obj.el).trigger('change'); + } + }, + + normMenu: function (menu) { + 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].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; + } + } + return menu; + } else if (typeof menu == 'function') { + return this.normMenu(menu()); + } 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 'checkbox': + input = ''; + break; + case 'radio': + input = ''; + // normalized options + var items = field.options.items ? field.options.items : field.html.items; + if (!$.isArray(items)) items = []; + if (items.length > 0) { + items = w2obj.field.prototype.normMenu(items); + } + // generate + for (var i = 0; i < items.length; i++) { + input += '
    '; + } + break; + case 'select': + input = ''; + break; + case 'textarea': + input = ''; + break; + case 'toggle': + input = '
    '; + break; + case 'html': + case 'custom': + case 'empty': + input = ''; + break; + + } + if (group !== ''){ + if(page != field.html.page || column != field.html.column || (field.html.group && (group != field.html.group))){ + pages[page][column] += '\n '; + group = ''; + } + } + if (field.html.group && (group != field.html.group)) { + html += '\n
    '+ field.html.group + '
    \n
    '; + group = field.html.group; + } + html += '\n
    '+ + '\n '+ + '\n
    '+ input + w2utils.lang(field.html.text) + '
    '+ + '\n
    '; + 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
    '; + 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
    '; + for (var a in this.actions) { // it is an object + var act = this.actions[a]; + var info = { caption: '', style: '', "class": '' }; + if ($.isPlainObject(act)) { + if (act.caption) info.caption = act.caption; + if (act.style) info.style = act.style; + if (act["class"]) info['class'] = act['class']; + } else { + info.caption = a; + if (['save', 'update', 'create'].indexOf(a.toLowerCase()) != -1) info['class'] = 'w2ui-btn-blue'; else info['class'] = ''; + } + buttons += '\n '; + } + buttons += '\n
    '; + } + html = ''; + for (var p = 0; p < pages.length; p++){ + html += '
    '; + for (var c = 0; c < pages[p].length; c++){ + html += '
    ' + (pages[p][c] || '') + '\n
    '; + } + html += '\n
    '; + } + html += buttons; + return html; + }, + + 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', click: click, 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 (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 (field) { + 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 }); + if (edata.isCancelled === true) return; + if (field != null) { + var from_field = obj.get(field, true); + var to_field = from_field + 1; + } 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).parents('.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(); + } + var from_field = 0; + var to_field = this.fields.length; + } + // refresh values of fields + for (var f = from_field; f < to_field; f++) { + var field = this.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 == null) { + console.log('ERROR: Cannot associate field "'+ field.name + '" with html control. Make sure html control exists with the same name.'); + //return; + } + if (field.el) field.el.id = field.name; + var tmp = $(field).data('w2field'); + if (tmp) tmp.clear(); + $(field.$el).off('change').on('change', function () { + var value_new = this.value; + var value_previous = obj.record[this.name] != null ? obj.record[this.name] : ''; + var field = obj.get(this.name); + if (['list', 'enum', 'file'].indexOf(field.type) != -1 && $(this).data('selected')) { + var nv = $(this).data('selected'); + var cv = obj.record[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); + } + // 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 }); + if (edata2.isCancelled === true) { + $(this).val(obj.record[this.name]); // return previous value + return; + } + // default action + var val = this.value; + if (this.type == 'select') val = this.value; + if (this.type == 'checkbox') val = this.checked ? true : false; + if (this.type == 'radio') { + field.$el.each(function (index, el) { + if (el.checked) val = el.value; + }); + } + if (['int', 'float', 'percent', 'money', 'currency', 'list', 'combo', 'enum', 'file', 'toggle'].indexOf(field.type) != -1) { + val = 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.record[this.name] = val; + // 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) { + if (field.disabled) { + $(field.el).prop('readonly', true); + } else { + $(field.el).prop('readonly', false); + } + } + // hidden + if (field.hidden) { + $(field.el).parent().parent().hide(); + } else { + $(field.el).parent().parent().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 = from_field; f < to_field; f++) { + var field = this.fields[f]; + var value = (this.record[field.name] != null ? this.record[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.record[field.name] = (value ? value : false); + 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 ($.isArray(items) && items.length > 0 && !$.isPlainObject(items[0])) { + field.options.items = w2obj.field.prototype.normMenu(items); + } + // find value from items + for (var i = 0; i < field.options.items.length; i++) { + var item = field.options.items[i]; + if (item.id == tmp_value) { + value = $.extend(true, {}, item); + obj.record[field.name] = value; + break; + } + } + } 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': + if (!$.isArray(value)) value = []; + $(field.el).w2field($.extend({}, field.options, { type: field.type, selected: value })); + break; + + // standard HTML + case 'select': + // generate options + var items = field.options.items; + if (items != null && items.length > 0) { + items = w2obj.field.prototype.normMenu(items); + $(field.el).html(''); + for (var it = 0; it < items.length; it++) { + $(field.el).append('";n.addClass("w2ui-editable").html('"+h.outTag),setTimeout(function(){n.find("select").on("change",function(a){delete f.last.move}).on("blur",function(a){1!=$(this).data("keep-open")&&f.editChange.call(f,this,g,b,a)})},10);break;case"div":var t=m.find("[col="+b+"] > div"),u="font-family: "+t.css("font-family")+"; font-size: "+t.css("font-size")+";";n.addClass("w2ui-editable").html('
    "+h.outTag),null==c&&n.find("div.w2ui-input").text("object"!=typeof o?o:"");var v=n.find("div.w2ui-input").get(0);setTimeout(function(){var a=v;$(a).on("blur",function(c){1!=$(this).data("keep-open")&&f.editChange.call(f,a,g,b,c)})},10),null!=c&&$(v).text("object"!=typeof o?o:"");break;default:var t=m.find("[col="+b+"] > div"),u="font-family: "+t.css("font-family")+"; font-size: "+t.css("font-size");n.addClass("w2ui-editable").html('"+h.outTag),"number"==h.type&&(o=w2utils.formatNumber(o)),"date"==h.type&&(o=w2utils.formatDate(w2utils.isDate(o,h.format,!0),h.format)),null==c&&n.find("input").val("object"!=typeof o?o:"");var v=n.find("input").get(0);$(v).w2field(h.type,$.extend(h,{selected:o})),setTimeout(function(){var a=v;"list"==h.type&&(a=$($(v).data("w2field").helpers.focus).find("input"),"object"!=typeof o&&""!=o&&a.val(o).css({opacity:1}).prev().css({opacity:1}),n.find("input").on("change",function(a){f.editChange.call(f,v,g,b,a)})),$(a).on("blur",function(a){1!=$(this).data("keep-open")&&f.editChange.call(f,v,g,b,a)})},10),null!=c&&$(v).val("object"!=typeof o?o:"")}setTimeout(function(){n.find("input, select, div.w2ui-input").data("old_value",p).on("mousedown",function(a){a.stopPropagation()}).on("click",function(a){"div"==h.type?e.call(n.find("div.w2ui-input")[0],null):e.call(n.find("input, select")[0],null)}).on("paste",function(a){var b=a.originalEvent;a.preventDefault();var c=b.clipboardData.getData("text/plain");document.execCommand("insertHTML",!1,c)}).on("keydown",function(c){var d=this,k="DIV"==d.tagName.toUpperCase()?$(d).text():$(d).val();switch(c.keyCode){case 8:"list"!=h.type||$(v).data("w2field")||c.preventDefault();break;case 9:case 13:c.preventDefault();break;case 37:0===w2utils.getCursorPosition(d)&&c.preventDefault();break;case 39:w2utils.getCursorPosition(d)==k.length&&(w2utils.setCursorPosition(d,k.length),c.preventDefault())}setTimeout(function(){switch(c.keyCode){case 9:var h=a,k=c.shiftKey?f.prevCell(g,b,!0):f.nextCell(g,b,!0);if(null==k){var l=c.shiftKey?f.prevRow(g,b):f.nextRow(g,b);if(null!=l&&l!=g){h=f.records[l].recid;for(var m=0;m0&&(a.focus(),clearTimeout(f.last.kbd_timer),"SELECT"!=a[0].tagName&&w2utils.setCursorPosition(a[0],b),a[0].resize=e,e.call(a[0],null))},50),f.trigger($.extend(l,{phase:"after",input:n.find("input, select, div.w2ui-input")}))},5)}}},editChange:function(a,b,c,d){var e=this;setTimeout(function(){var a=$(e.box).find("#grid_"+e.name+"_focus");a.is(":focus")||a.focus()},10);var f=b<0;b=b<0?-b-1:b;var g=f?this.summary:this.records,h=g[b],i=this.columns[c],j=$("#grid_"+this.name+(i.frozen===!0?"_frec_":"_rec_")+w2utils.escapeId(h.recid)),k=a.tagName&&"DIV"==a.tagName.toUpperCase()?$(a).text():a.value,l=this.parseField(h,i.field),m=$(a).data("w2field");m&&("list"==m.type&&(k=$(a).data("selected")),($.isEmptyObject(k)||null==k)&&(k=""),$.isPlainObject(k)||(k=m.clean(k))),"checkbox"==a.type&&(h.w2ui&&h.w2ui.editable===!1&&(a.checked=!a.checked),k=a.checked);var n={phase:"before",type:"change",target:this.name,input_id:a.id,recid:h.recid,index:b,column:c,originalEvent:d.originalEvent?d.originalEvent:d,value_new:k,value_previous:h.w2ui&&h.w2ui.changes&&h.w2ui.changes.hasOwnProperty(i.field)?h.w2ui.changes[i.field]:l,value_original:l};for(null!=$(d.target).data("old_value")&&(n.value_previous=$(d.target).data("old_value"));;){if(k=n.value_new,"object"!=typeof k&&String(l)!=String(k)||"object"==typeof k&&k.id!=l&&("object"!=typeof l||null==l||k.id!=l.id)){if(n=this.trigger($.extend(n,{type:"change",phase:"before"})),n.isCancelled!==!0){if(k!==n.value_new)continue;h.w2ui=h.w2ui||{},h.w2ui.changes=h.w2ui.changes||{},h.w2ui.changes[i.field]=n.value_new,this.trigger($.extend(n,{phase:"after"}))}}else if(n=this.trigger($.extend(n,{type:"restore",phase:"before"})),n.isCancelled!==!0){if(k!==n.value_new)continue;h.w2ui&&h.w2ui.changes&&delete h.w2ui.changes[i.field],h.w2ui&&$.isEmptyObject(h.w2ui.changes)&&delete h.w2ui.changes,this.trigger($.extend(n,{phase:"after"}))}break}var o=$(j).find("[col="+c+"]");f||(h.w2ui&&h.w2ui.changes&&null!=h.w2ui.changes[i.field]?o.addClass("w2ui-changed"):o.removeClass("w2ui-changed"),o.replaceWith(this.getCellHTML(b,c,f))),$(this.box).find("div.w2ui-edit-box").remove(),this.show.toolbarSave&&(this.getChanges().length>0?this.toolbar.enable("w2ui-save"):this.toolbar.disable("w2ui-save"))},delete:function(a){var b=((new Date).getTime(),this),c=this.trigger({phase:"before",target:this.name,type:"delete",force:a});if(c.isCancelled!==!0){a=c.force,setTimeout(function(){$().w2tag()},20);var d=this.getSelection();if(0!==d.length){if(""!=this.msgDelete&&!a)return void this.message({width:350,height:170,body:'
    '+w2utils.lang(b.msgDelete)+"
    ",buttons:'",onOpen:function(a){var c=$(this.box).find("input, textarea, select, button");c.off(".message").on("blur.message",function(a){c.index(a.target)+1===c.length&&(c.get(0).focus(),a.preventDefault())}).on("keydown.message",function(a){27==a.keyCode&&b.message()}),setTimeout(function(){$(this.box).find(".w2ui-btn:last-child").focus(),clearTimeout(b.last.kbd_timer)},25)}});this.message();var e="object"!=typeof this.url?this.url:this.url.remove;if(e)this.request("delete");else if("object"!=typeof d[0])this.selectNone(),this.remove.apply(this,d);else{for(var f=0;f0&&e.multiSelect){if(i[0].recid){var l=this.get(i[0].recid,!0),m=this.get(a,!0);if(d>i[0].column)var n=i[0].column,o=d;else var n=d,o=i[0].column;for(var p=n;p<=o;p++)k.push(p)}else var l=this.get(f,!0),m=this.get(a,!0);var q=[];if(l>m){var g=l;l=m,m=g}for(var r="object"!=typeof this.url?this.url:this.url.get,s=l;s<=m;s++)if(!(this.searchData.length>0)||r||$.inArray(s,this.last.searchIds)!=-1)if("row"==this.selectType)q.push(this.records[s].recid);else for(var t=0;t300?this.selectNone():this.unselect.apply(this,i),v===!0&&1==i.length?this.unselect({recid:a,column:d}):this.select({recid:a,column:d}))}this.status(),e.initResize(),this.trigger($.extend(h,{phase:"after"}))}}},columnClick:function(a,b){var c=this.trigger({phase:"before",type:"columnClick",target:this.name,field:a,originalEvent:b});if(c.isCancelled!==!0){if("row"==this.selectType){var d=this.getColumn(a);d&&d.sortable&&this.sort(a,null,!(!b||!b.ctrlKey&&!b.metaKey)),"line-number"==c.field&&(this.getSelection().length>=this.records.length?this.selectNone():this.selectAll())}else if("line-number"==c.field)this.getSelection().length>=this.records.length?this.selectNone():this.selectAll();else{b.shiftKey||b.metaKey||b.ctrlKey||this.selectNone();var e=this.getSelection(),d=this.getColumn(c.field,!0),f=[],g=[];if(0!=e.length&&b.shiftKey){var h=d,i=e[0].column;h>i&&(h=e[0].column,i=d);for(var j=h;j<=i;j++)g.push(j)}else g.push(d);var c=this.trigger({phase:"before",type:"columnSelect",target:this.name,columns:g});if(c.isCancelled!==!0){for(var j=0;j1){for(var a=0;a1&&(i.splice(i.indexOf(d.records[d.last.sel_ind].recid),1),d.unselect.apply(d,i),!0)}var d=this,e="object"!=typeof this.url?this.url:this.url.get;if(d.keyboard===!0){var f=d.trigger({phase:"before",type:"keydown",target:d.name,originalEvent:a});if(f.isCancelled!==!0){if($(this.box).find(">.w2ui-message").length>0)return void(27==a.keyCode&&this.message());var g=!1,h=$("#grid_"+d.name+"_records"),i=d.getSelection();0===i.length&&(g=!0);var j=i[0]||null,k=[],l=i[i.length-1];if("object"==typeof j&&null!=j){j=i[0].recid,k=[];for(var m=0;;){if(!i[m]||i[m].recid!=j)break;k.push(i[m].column),m++}l=i[i.length-1].recid}var n=d.get(j,!0),o=d.get(l,!0),p=(d.get(j),$("#grid_"+d.name+"_rec_"+(null!=n?w2utils.escapeId(d.records[n].recid):"none"))),q=!1,r=a.keyCode,s=a.shiftKey;switch(r){case 8:case 46:(this.show.toolbarDelete||this.onDelete)&&d.delete(),q=!0,a.stopPropagation();break;case 27:d.selectNone(),q=!0;break;case 65:if(!a.metaKey&&!a.ctrlKey)break;d.selectAll(),q=!0;break;case 13:if("row"==this.selectType&&d.show.expandColumn===!0){if(p.length<=0)break;d.toggle(j,a),q=!0}else{for(var t=0;t0&&(d.editField(j,k[0],null,a),q=!0)}break;case 37:if(g){b();break}if("row"==this.selectType){if(p.length<=0)break;var v=this.records[n].w2ui||{};!v||null==v.parent_recid||Array.isArray(v.children)&&0!==v.children.length&&v.expanded?d.collapse(j,a):(d.unselect(j),d.collapse(v.parent_recid,a),d.select(v.parent_recid))}else{var w=d.prevCell(n,k[0]);if(s||null!=w||(this.selectNone(),w=0),null!=w)if(s&&d.multiSelect){if(c())return;var v=[],x=[],y=[];if(0===k.indexOf(this.last.sel_col)&&k.length>1){for(var z=0;z1)d.selectNone();else for(var A=1;A1){for(var z=0;z1)d.selectNone();else for(var A=0;Aw&&d.last.sel_ind!=o?d.unselect(d.records[o].recid):d.select(d.records[w].recid);else if(d.last.sel_ind>w&&d.last.sel_ind!=o){w=o;for(var v=[],t=0;t300?this.selectNone():this.unselect.apply(this,i),d.click({recid:d.records[w].recid,column:k[0]},a);d.scrollIntoView(w),a.preventDefault&&a.preventDefault()}else if(!s)if(i.length>1)d.selectNone();else for(var A=1;A300?this.selectNone():this.unselect.apply(this,i),d.click({recid:d.records[B].recid,column:k[0]},a);d.scrollIntoView(B),q=!0}else if(!s)if(i.length>1)d.selectNone();else for(var A=0;A0&&(a=this.last.searchIds.indexOf(a)),f.height()0?g:d)&&f.length>0){var h=Math.floor(f[0].scrollTop/this.recordHeight),i=h+Math.floor(f.height()/this.recordHeight);a==h&&(c===!0?f.prop({scrollTop:f.scrollTop()-f.height()/1.3}):(f.stop(),f.animate({scrollTop:f.scrollTop()-f.height()/1.3},250,"linear"))),a==i&&(c===!0?f.prop({scrollTop:f.scrollTop()+f.height()/1.3}):(f.stop(),f.animate({scrollTop:f.scrollTop()+f.height()/1.3},250,"linear"))),(ai)&&(c===!0?f.prop({scrollTop:(a-1)*this.recordHeight}):(f.stop(),f.animate({scrollTop:(a-1)*this.recordHeight},250,"linear")))}if(null!=b){for(var j=0,k=0,l=w2utils.scrollBarSize(),m=0;m<=b;m++){var n=this.columns[m];n.frozen||n.hidden||(j=k,k+=parseInt(n.sizeCalculated))}f.width()0&&$(d.box).find(c.target).w2menu(d.menu,{originalEvent:c,contextMenu:!0,onSelect:function(b){d.menuClick(a,parseInt(b.index),b.originalEvent)}}),c.preventDefault&&c.preventDefault(),d.trigger($.extend(i,{phase:"after"})))}},menuClick:function(a,b,c){var d=this,e=d.trigger({phase:"before",type:"menuClick",target:d.name,originalEvent:c,recid:a,menuIndex:b,menuItem:d.menu[b]});e.isCancelled!==!0&&d.trigger($.extend(e,{phase:"after"}))},toggle:function(a){var b=this.get(a);return b.w2ui=b.w2ui||{},b.w2ui.expanded===!0?this.collapse(a):this.expand(a)},expand:function(a){var b=this.get(a,!0),c=this.records[b];c.w2ui=c.w2ui||{};var d=w2utils.escapeId(a),e=c.w2ui.children;if(Array.isArray(e)){if(c.w2ui.expanded===!0||0===e.length)return!1;var f=this.trigger({phase:"before",type:"expand",target:this.name,recid:a});if(f.isCancelled===!0)return!1;c.w2ui.expanded=!0,e.forEach(function(a){a.w2ui=a.w2ui||{},a.w2ui.parent_recid=c.recid,null==a.w2ui.children&&(a.w2ui.children=[])}),this.records.splice.apply(this.records,[b+1,0].concat(e)),this.total+=e.length;var g="object"!=typeof this.url?this.url:this.url.get;g||(this.localSort(!0,!0),this.searchData.length>0&&this.localSearch(!0)),this.refresh(),this.trigger($.extend(f,{phase:"after"}))}else{if($("#grid_"+this.name+"_rec_"+d+"_expanded_row").length>0||this.show.expandColumn!==!0)return!1;if("none"==c.w2ui.expanded)return!1;$("#grid_"+this.name+"_rec_"+d).after('
    '),$("#grid_"+this.name+"_frec_"+d).after(''+(this.show.lineNumbers?'':"")+'
    ');var f=this.trigger({phase:"before",type:"expand",target:this.name,recid:a,box_id:"grid_"+this.name+"_rec_"+a+"_expanded",fbox_id:"grid_"+this.name+"_frec_"+d+"_expanded"});if(f.isCancelled===!0)return $("#grid_"+this.name+"_rec_"+d+"_expanded_row").remove(),$("#grid_"+this.name+"_frec_"+d+"_expanded_row").remove(),!1;var h=$(this.box).find("#grid_"+this.name+"_rec_"+a+"_expanded"),i=$(this.box).find("#grid_"+this.name+"_frec_"+a+"_expanded"),j=h.find("> div:first-child").height();h.height()=0)break;l++}this.records.splice(k,l-k+1),this.total-=l-k+1;var m="object"!=typeof this.url?this.url:this.url.get;m||this.searchData.length>0&&this.localSearch(!0),this.refresh(),c.trigger($.extend(h,{phase:"after"}))}else{if(0===$("#grid_"+this.name+"_rec_"+f+"_expanded_row").length||this.show.expandColumn!==!0)return!1;var h=this.trigger({phase:"before",type:"collapse",target:this.name,recid:a,box_id:"grid_"+this.name+"_rec_"+f+"_expanded",fbox_id:"grid_"+this.name+"_frec_"+f+"_expanded"});if(h.isCancelled===!0)return!1;$("#grid_"+this.name+"_rec_"+f).removeAttr("expanded").removeClass("w2ui-expanded"),$("#grid_"+this.name+"_frec_"+f).removeAttr("expanded").removeClass("w2ui-expanded"),$("#grid_"+this.name+"_cell_"+this.get(a,!0)+"_expand div").html("+"),$("#grid_"+c.name+"_rec_"+f+"_expanded").css("height","0px"),$("#grid_"+c.name+"_frec_"+f+"_expanded").css("height","0px"),setTimeout(function(){$("#grid_"+c.name+"_rec_"+f+"_expanded_row").remove(),$("#grid_"+c.name+"_frec_"+f+"_expanded_row").remove(),e.w2ui.expanded=!1,c.trigger($.extend(h,{phase:"after"})),c.resizeRecords()},300)}return!0},sort:function(a,b,c){var d=this.trigger({phase:"before",type:"sort",target:this.name,field:a,direction:b,multiField:c});if(d.isCancelled!==!0){if(null!=a){for(var e=this.sortData.length,f=0;f0&&this.localSearch(!0),this.last.scrollTop=0,$("#grid_"+this.name+"_records").prop("scrollTop",0),this.trigger($.extend(d,{phase:"after"})),this.refresh())}},copy:function(a,b){if($.isPlainObject(a))return this.trigger($.extend(a,{phase:"after"})),a.text;var c=this.getSelection();if(0===c.length)return"";var d="";if("object"==typeof c[0]){for(var e=c[0].column,f=c[0].column,g=[],h=0;hf&&(f=c[h].column),g.indexOf(c[h].index)==-1&&g.push(c[h].index);g.sort(function(a,b){return a-b});for(var i=0;i div.w2ui-grid-box").css("width",$(this.box).width()).css("height",$(this.box).height());var c=this.trigger({phase:"before",type:"resize",target:this.name});if(c.isCancelled!==!0)return a.resizeBoxes(),a.resizeRecords(),a.toolbar&&a.toolbar.resize&&a.toolbar.resize(),this.trigger($.extend(c,{phase:"after"})),(new Date).getTime()-b}},update:function(a){var b=(new Date).getTime();if(null==this.box)return 0;if(null==a){for(var c=this.last.range_start-1;c<=this.last.range_end-1;c++)if(!(c<0)){var d=this.records[c]||{};d.w2ui||(d.w2ui={});for(var e=0;e0){null==b&&(b=this.get(a,!0));var e=c.attr("line"),f=!this.records[b]||this.records[b].recid!=a,g="object"!=typeof this.url?this.url:this.url.get;if(this.searchData.length>0&&!g)for(var h=0;h0&&(this.last.field=this.searches[0].field,this.last.caption=this.searches[0].caption);for(var h=0;h0&&k.indexes.length==this.records.length,m=k.indexes.length>0&&0!==this.searchData.length&&k.indexes.length==this.last.searchIds.length;l||m?$("#grid_"+this.name+"_check_all").prop("checked",!0):$("#grid_"+this.name+"_check_all").prop("checked",!1),this.status();for(var n=a.find({"w2ui.expanded":!0},!0),o=0;o0&&$(a.box).find(".w2ui-grid-data > div").w2marker(b)},50),this.show.toolbarSave&&(this.getChanges().length>0?this.toolbar.enable("w2ui-save"):this.toolbar.disable("w2ui-save")),this.trigger($.extend(d,{phase:"after"})),a.resize(),a.addRange("selection"),setTimeout(function(){a.resize(),a.scroll()},1),a.reorderColumns&&!a.last.columnDrag?a.last.columnDrag=a.initColumnDrag():!a.reorderColumns&&a.last.columnDrag&&a.last.columnDrag.remove(),(new Date).getTime()-b}}},refreshBody:function(){var a=this.find({"w2ui.summary":!0},!0);if(a.length>0){for(var b=0;b=0;b--)this.records.splice(a[b],1)}this.scroll();var c=this.getRecordsHTML(),d=this.getColumnsHTML(),e='
    '+c[0]+'
    "+c[1]+'
    '+d[0]+'
    '+d[1]+"
    ";if($("#grid_"+this.name+"_body").html(e),0===this.records.length&&this.msgEmpty?$("#grid_"+this.name+"_body").append('
    '+this.msgEmpty+"
    "):$("#grid_"+this.name+"_empty_msg").length>0&&$("#grid_"+this.name+"_empty_msg").remove(),this.summary.length>0){var f=this.getSummaryHTML();$("#grid_"+this.name+"_fsummary").html(f[0]).show(),$("#grid_"+this.name+"_summary").html(f[1]).show()}else $("#grid_"+this.name+"_fsummary").hide(),$("#grid_"+this.name+"_summary").hide()},render:function(a){function b(a){if(1==a.which&&("text"==e.last.userSelect&&(delete e.last.userSelect,$(e.box).find(".w2ui-grid-body").css(w2utils.cssPrefix("user-select","none"))),!("row"==e.selectType&&($(a.target).parents().hasClass("w2ui-head")||$(a.target).hasClass("w2ui-head"))||e.last.move&&"expand"==e.last.move.type))){if(a.altKey)$(e.box).find(".w2ui-grid-body").css(w2utils.cssPrefix("user-select","text")),e.selectNone(),e.last.move={type:"text-select"},e.last.userSelect="text";else if(e.multiSelect||e.reorderRows){for(var b=a.target,f={x:a.offsetX-10,y:a.offsetY-10},g=!1;b&&(!b.classList||!b.classList.contains("w2ui-grid"));)b.tagName&&"TD"==b.tagName.toUpperCase()&&(g=!0),b.tagName&&"TR"!=b.tagName.toUpperCase()&&1==g&&(f.x+=b.offsetLeft,f.y+=b.offsetTop),b=b.parentNode;e.last.move={x:a.screenX,y:a.screenY,divX:0,divY:0,focusX:f.x,focusY:f.y,recid:$(a.target).parents("tr").attr("recid"),column:parseInt("TD"==a.target.tagName.toUpperCase()?$(a.target).attr("col"):$(a.target).parents("td").attr("col")),type:"select",ghost:!1,start:!0},null==e.last.move.recid&&(e.last.move.type="select-column");var h=a.target,i=$(e.box).find("#grid_"+e.name+"_focus");if(e.last.move){var j=e.last.move.focusX,k=e.last.move.focusY,l=$(h).parents("table").parent();(l.hasClass("w2ui-grid-records")||l.hasClass("w2ui-grid-frecords")||l.hasClass("w2ui-grid-columns")||l.hasClass("w2ui-grid-fcolumns")||l.hasClass("w2ui-grid-summary"))&&(j=e.last.move.focusX-$(e.box).find("#grid_"+e.name+"_records").scrollLeft(),k=e.last.move.focusY-$(e.box).find("#grid_"+e.name+"_records").scrollTop()),($(h).hasClass("w2ui-grid-footer")||$(h).parents("div.w2ui-grid-footer").length>0)&&(k=$(e.box).find("#grid_"+e.name+"_footer").position().top),i.css({left:j-10,top:k})}setTimeout(function(){["INPUT","TEXTAREA","SELECT"].indexOf(h.tagName.toUpperCase())!=-1?$(h).focus():i.is(":focus")||i.focus()},50)}if(1==e.reorderRows){var m=a.target;if("TD"!=m.tagName.toUpperCase()&&(m=$(m).parents("td")[0]),$(m).hasClass("w2ui-col-number")){e.selectNone(),e.last.move.reorder=!0;var n=$(e.box).find(".w2ui-even.w2ui-empty-record").css("background-color"),o=$(e.box).find(".w2ui-odd.w2ui-empty-record").css("background-color");$(e.box).find(".w2ui-even td").not(".w2ui-col-number").css("background-color",n),$(e.box).find(".w2ui-odd td").not(".w2ui-col-number").css("background-color",o);var p=e.last.move;if(!p.ghost){var q=$("#grid_"+e.name+"_rec_"+p.recid),b=q.parents("table").find("tr:first-child").clone();p.offsetY=a.offsetY,p.from=p.recid,p.pos=q.position(),p.ghost=$(q).clone(!0),p.ghost.removeAttr("id"),q.find("td").remove(),q.append('');var r=$(e.box).find(".w2ui-grid-records");r.append('
    '),$("#grid_"+e.name+"_ghost").append(b).append(p.ghost)}var s=$("#grid_"+e.name+"_ghost"),r=$(e.box).find(".w2ui-grid-records");s.css({top:p.pos.top+r.scrollTop(),left:p.pos.left,"border-top":"1px solid #aaa","border-bottom":"1px solid #aaa"})}else e.last.move.reorder=!1}$(document).on("mousemove",c),$(document).on("mouseup",d),a.stopPropagation()}}function c(a){var b=e.last.move;if(b&&["select","select-column"].indexOf(b.type)!=-1&&(b.divX=a.screenX-b.x,b.divY=a.screenY-b.y,!(Math.abs(b.divX)<=1&&Math.abs(b.divY)<=1))){if(e.last.cancelClick=!0,1==e.reorderRows&&e.last.move.reorder){var c=$(a.target).parents("tr"),d=c.attr("recid");if(d!=b.from){var f=($("#grid_"+e.name+"_rec_"+b.recid),$("#grid_"+e.name+"_rec_"+d));$(e.box).find(".tmp-ghost").css("border-top","0px"),f.addClass("tmp-ghost").css("border-top","2px solid #769EFC"),b.lastY=a.screenY,b.to=d}var g=$("#grid_"+e.name+"_ghost"),h=$(e.box).find(".w2ui-grid-records");return void g.css({top:b.pos.top+b.divY+h.scrollTop(),left:b.pos.left})}b.start&&b.recid&&(e.selectNone(),b.start=!1);var i=[],d="TR"==a.target.tagName.toUpperCase()?$(a.target).attr("recid"):$(a.target).parents("tr").attr("recid");if(null==d){if("row"==e.selectType)return;if(e.last.move&&"select"==e.last.move.type)return;var j=parseInt($(a.target).parents("td").attr("col"));if(isNaN(j))e.removeRange("column-selection"),$(e.box).find(".w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header").removeClass("w2ui-col-selected"),$(e.box).find(".w2ui-col-number").removeClass("w2ui-row-selected"),delete b.colRange;else{var k=j+"-"+j;b.columnj&&(k=j+"-"+b.column);for(var l=[],c=k.split("-"),n=parseInt(c[0]);n<=parseInt(c[1]);n++)l.push(n);if(b.colRange!=k&&(m=e.trigger({phase:"before",type:"columnSelect",target:e.name,columns:l,isCancelled:!1}),m.isCancelled!==!0)){null==b.colRange&&e.selectNone();var c=k.split("-");$(e.box).find(".w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header").removeClass("w2ui-col-selected");for(var o=parseInt(c[0]);o<=parseInt(c[1]);o++)$(e.box).find("#grid_"+e.name+"_column_"+o+" .w2ui-col-header").addClass("w2ui-col-selected");$(e.box).find(".w2ui-col-number").not(".w2ui-head").addClass("w2ui-row-selected"),b.colRange=k,e.removeRange("column-selection"),e.addRange({name:"column-selection",range:[{recid:e.records[0].recid,column:c[0]},{recid:e.records[e.records.length-1].recid,column:c[1]}],style:"background-color: rgba(90, 145, 234, 0.1)"})}}}else{var p=e.get(b.recid,!0);if(null==p||e.records[p]&&e.records[p].recid!=b.recid)return;var q=e.get(d,!0);if(null==q)return;var r=parseInt(b.column),s=parseInt("TD"==a.target.tagName.toUpperCase()?$(a.target).attr("col"):$(a.target).parents("td").attr("col"));if(isNaN(r)&&isNaN(s)&&(r=0,s=e.columns.length-1),p>q){var c=p;p=q,q=c}var c="ind1:"+p+",ind2;"+q+",col1:"+r+",col2:"+s;if(b.range==c)return;b.range=c;for(var t=p;t<=q;t++)if(!(e.last.searchIds.length>0&&e.last.searchIds.indexOf(t)==-1))if("row"!=e.selectType){if(r>s){var c=r;r=s,s=c}for(var c=[],u=r;u<=s;u++)e.columns[u].hidden||i.push({recid:e.records[t].recid,column:parseInt(u)})}else i.push(e.records[t].recid);if("row"!=e.selectType){for(var v=e.getSelection(),c=[],w=0;wn?e.records.splice(n,0,f):e.records.splice(n-1,0,f)),$("#grid_"+e.name+"_ghost").remove(),e.refresh(),e.trigger($.extend(k,{phase:"after"}))}}delete e.last.move,$(document).off("mousemove",c),$(document).off("mouseup",d)}}var e=this,f=(new Date).getTime();if(null!=a&&($(this.box).find("#grid_"+this.name+"_body").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-grid").html(""),this.box=a),this.box){var g="object"!=typeof this.url?this.url:this.url.get,h=this.trigger({phase:"before",target:this.name,type:"render",box:a});if(h.isCancelled!==!0){if(this.reset(!0),!this.last.field)if(this.multiSearch&&this.show.searchAll)this.last.field="all",this.last.caption=w2utils.lang("All Fields");else{for(var i=0;i=this.searches.length?(this.last.field="",this.last.caption=""):(this.last.field=this.searches[i].field,this.last.caption=this.searches[i].caption)}if($(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-grid").html('
    '),"row"!=this.selectType&&$(this.box).addClass("w2ui-ss"),$(this.box).length>0&&($(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){var j=this.searchData;setTimeout(function(){e.initAllField(e.last.field,1==j.length?j[0].value:null)},1)}$("#grid_"+this.name+"_footer").html(this.getFooterHTML()),this.last.state||(this.last.state=this.stateSave(!0)),this.stateRestore(),g&&this.refresh();for(var k=!1,l=0;l0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-grid").html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})))},initColumnOnOff:function(){if(this.show.toolbarColumns){for(var a=this,b='
    ",c=0;c ")}var f="object"!=typeof this.url?this.url:this.url.get;(f&&a.show.skipRecords||a.show.saveRestoreState)&&(b+=''),f&&a.show.skipRecords&&(b+='"),a.show.saveRestoreState&&(b+='"),b+="
    '+w2utils.lang("Skip")+' "+w2utils.lang("Records")+"
    "+w2utils.lang("Save Grid State")+'
    "+w2utils.lang("Restore Default State")+"
    ",this.toolbar.get("w2ui-column-on-off").html=b}},initColumnDrag:function(a){function b(){j.pressed=!1,clearTimeout(j.timeout)}function c(a){j.timeout&&clearTimeout(j.timeout);var b=this;j.pressed=!0,j.timeout=setTimeout(function(){if(j.pressed){var c,f,g,h,k,l=["w2ui-col-number","w2ui-col-expand","w2ui-col-select"],m=["w2ui-head-last"],n=l.concat(m),o=".w2ui-col-number, .w2ui-col-expand, .w2ui-col-select",p=".w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select";if($(a.originalEvent.target).parents().hasClass("w2ui-head")){for(var q=0,r=n.length;q
    '),j.markerLeft=$('
    ')),j.lastInt&&j.lastInt===a||(j.lastInt=a,j.marker.remove(),j.markerLeft.remove(),$(".w2ui-head").removeClass("w2ui-col-intersection"),a>=j.columns.length?($(j.columns[j.columns.length-1]).children("div:last").append(j.marker.addClass("right").removeClass("left")),$(j.columns[j.columns.length-1]).addClass("w2ui-col-intersection")):a<=j.numberPreColumnsPresent?($(j.columns[j.numberPreColumnsPresent]).prepend(j.marker.addClass("left").removeClass("right")).css({position:"relative"}),$(j.columns[j.numberPreColumnsPresent]).prev().addClass("w2ui-col-intersection")):($(j.columns[a]).children("div:last").prepend(j.marker.addClass("left").removeClass("right")),$(j.columns[a]).prev().children("div:last").append(j.markerLeft.addClass("right").removeClass("left")).css({position:"relative"}),$(j.columns[a-1]).addClass("w2ui-col-intersection")))}function g(a,b,c){if(a<=b[0])return 0;if(a>=b[b.length-1]+c)return b.length;for(var d=0,e=b.length;df&&a<=h)return d;if(a>h&&a<=g)return d+1}return intersection}function h(a,b){$(j.ghost).css({left:a-10,top:b-10})}if(this.columnGroups&&this.columnGroups.length)throw"Draggable columns are not currently supported with column groups.";var i=this,j={};return j.lastInt=null,j.pressed=!1,j.timeout=null,j.columnHead=null,$(i.box).on("mousedown",c),$(i.box).on("mouseup",b),{remove:function(){$(i.box).off("mousedown",c),$(i.box).off("mouseup",b),$(i.box).find(".w2ui-head").removeAttr("draggable"),i.last.columnDrag=!1}}},columnOnOff:function(a,b){var c=$(a.target).parents("tr").find(".w2ui-column-check"),d=this.trigger({phase:"before",target:this.name,type:"columnOnOff",field:b,originalEvent:a});if(d.isCancelled!==!0){for(var e=this,f=e.find({"w2ui.expanded":!0},!0),g=0;g ';this.toolbar.items.push({type:"html",id:"w2ui-search",html:c})}if(this.show.toolbarSearch&&this.multiSearch&&this.searches.length>0&&this.toolbar.items.push($.extend(!0,{},this.buttons["search-go"])),(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"}),this.show.toolbarAdd&&this.toolbar.items.push($.extend(!0,{},this.buttons.add)),this.show.toolbarEdit&&this.toolbar.items.push($.extend(!0,{},this.buttons.edit)),this.show.toolbarDelete&&this.toolbar.items.push($.extend(!0,{},this.buttons.delete)),this.show.toolbarSave&&((this.show.toolbarAdd||this.show.toolbarDelete||this.show.toolbarEdit)&&this.toolbar.items.push({type:"break",id:"w2ui-break2"}),this.toolbar.items.push($.extend(!0,{},this.buttons.save))),b)for(var d=0;d0&&(c.css({bottom:0+(this.show.footer?w2utils.getSize(e,"height"):0)+"px"}),d.css({bottom:0+(this.show.footer?w2utils.getSize(e,"height"):0)+"px",right:"0px"})),this.show.footer&&e.css({bottom:"0px",left:"0px",right:"0px"}),f.css({top:0+(this.show.header?w2utils.getSize(a,"height"):0)+(this.show.toolbar?w2utils.getSize(b,"height"):0)+"px",bottom:0+(this.show.footer?w2utils.getSize(e,"height"):0)+(this.summary.length>0?w2utils.getSize(d,"height"):0)+"px",left:"0px",right:"0px"})},resizeRecords:function(){function a(a,b,c){var d="",e="",f="";d+='',e+='',c.show.lineNumbers&&(d+=''),c.show.selectColumn&&(d+=''),c.show.expandColumn&&(d+=''),e+='';for(var g=0;gc.last.colEnd)&&!h.frozen||(f='',h.frozen?d+=f:e+=f)}d+=' ',e+=' ',$("#grid_"+c.name+"_frecords > table").append(d),$("#grid_"+c.name+"_records > table").append(e)}var b=this;$(this.box).find(".w2ui-empty-record").remove();var c=$(this.box),d=$(this.box).find("> div.w2ui-grid-box"),e=$("#grid_"+this.name+"_header"),f=$("#grid_"+this.name+"_toolbar"),g=$("#grid_"+this.name+"_summary"),h=$("#grid_"+this.name+"_fsummary"),i=$("#grid_"+this.name+"_footer"),j=$("#grid_"+this.name+"_body"),k=$("#grid_"+this.name+"_columns"),l=$("#grid_"+this.name+"_fcolumns"),m=$("#grid_"+this.name+"_records"),n=$("#grid_"+this.name+"_frecords"),o=$("#grid_"+this.name+"_scroll1"),p=8*String(this.total).length+10;p<34&&(p=34),null!=this.lineNumberWidth&&(p=this.lineNumberWidth);for(var q=!1,r=!1,s=0,t=0;ttable").height()+(q?w2utils.scrollBarSize():0)&&(r=!0),this.fixedBody){var v=d.height()-(this.show.header?w2utils.getSize(e,"height"):0)-(this.show.toolbar?w2utils.getSize(f,"height"):0)-("none"!=g.css("display")?w2utils.getSize(g,"height"):0)-(this.show.footer?w2utils.getSize(i,"height"):0);j.css("height",v)}else{var v=w2utils.getSize(k,"height")+w2utils.getSize($("#grid_"+b.name+"_records table"),"height")+(q?w2utils.scrollBarSize():0);b.height=v+w2utils.getSize(d,"+height")+(b.show.header?w2utils.getSize(e,"height"):0)+(b.show.toolbar?w2utils.getSize(f,"height"):0)+("none"!=g.css("display")?w2utils.getSize(g,"height"):0)+(b.show.footer?w2utils.getSize(i,"height"):0),d.css("height",b.height),j.css("height",v),c.css("height",w2utils.getSize(d,"height")+w2utils.getSize(c,"+height"))}var w=this.records.length,x="object"!=typeof this.url?this.url:this.url.get;if(0==this.searchData.length||x||(w=this.last.searchIds.length),this.fixedBody||(r=!1),q||r?(k.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()).show(),m.css({top:(this.columnGroups.length>0&&this.show.columns?1:0)+w2utils.getSize(k,"height")+"px","-webkit-overflow-scrolling":"touch","overflow-x":q?"auto":"hidden","overflow-y":r?"auto":"hidden"})):(k.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").hide(),m.css({top:(this.columnGroups.length>0&&this.show.columns?1:0)+w2utils.getSize(k,"height")+"px",overflow:"hidden"}),m.length>0&&(this.last.scrollTop=0,this.last.scrollLeft=0)),q?(n.css("margin-bottom",w2utils.scrollBarSize()),o.show()):(n.css("margin-bottom",0),o.hide()),n.css({overflow:"hidden",top:m.css("top")}),this.show.emptyRecords&&!r){var y=Math.floor(m.height()/this.recordHeight)-1,z=0;if(m[0]&&(z=m[0].scrollHeight-y*this.recordHeight),z>=this.recordHeight&&(z-=this.recordHeight,y++),this.fixedBody){for(var A=w;A0){for(var B=parseInt(j.width())-(r?w2utils.scrollBarSize():0)-(this.show.lineNumbers?p:0)-(this.show.selectColumn?26:0)-(this.show.expandColumn?26:0)-1,C=B,D=0,E=!1,t=0;t0&&(F.gridMinWidth>C&&F.hidden!==!0&&(F.hidden=!0,E=!0),F.gridMinWidth0)for(var t=0;tparseInt(F.max)&&(F.sizeCalculated=F.max+"px"),G+=parseInt(F.sizeCalculated))}var H=parseInt(C)-parseInt(G);if(H>0&&D>0)for(var t=0;;){var F=this.columns[t];if(null!=F)if(F.hidden||"px"==F.sizeType)t++;else{if(F.sizeCalculated=parseInt(F.sizeCalculated)+1+"px",H--,0===H)break;t++}else t=0}else H>0&&k.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()).show();var I=1;this.show.lineNumbers&&(I+=p),this.show.selectColumn&&(I+=26),this.show.expandColumn&&(I+=26);for(var t=0;t table > tbody > tr:nth-child(1) td").add(l.find("> table > tbody > tr:nth-child(1) td")).each(function(a,c){$(c).hasClass("w2ui-col-number")&&$(c).css("width",p);var d=$(c).attr("col");if(null!=d){if("start"==d){for(var e=0,f=0;f0&&0===D?H:0)+"px")}),3==k.find("> table > tbody > tr").length&&k.find("> table > tbody > tr:nth-child(1) td").add(l.find("> table > tbody > tr:nth-child(1) td")).html("").css({height:"0px",border:"0px",padding:"0px",margin:"0px"}),m.find("> table > tbody > tr:nth-child(1) td").add(n.find("> table > tbody > tr:nth-child(1) td")).each(function(a,c){$(c).hasClass("w2ui-col-number")&&$(c).css("width",p);var d=$(c).attr("col");if(null!=d){if("start"==d){for(var e=0,f=0;f0&&0===D?H:0)+"px")}),g.find("> table > tbody > tr:nth-child(1) td").add(h.find("> table > tbody > tr:nth-child(1) td")).each(function(a,c){$(c).hasClass("w2ui-col-number")&&$(c).css("width",p);var d=$(c).attr("col");if(null!=d){if("start"==d){for(var e=0,f=0;f0&&0===D?H:0)+"px")}),this.initResize(),this.refreshRanges(),(this.last.scrollTop||this.last.scrollLeft)&&m.length>0&&(k.prop("scrollLeft",this.last.scrollLeft),m.prop("scrollTop",this.last.scrollTop),m.prop("scrollLeft",this.last.scrollLeft))},getSearchesHTML:function(){function a(a,c){var d="",e=b.operators[b.operatorsMap[a]];null!=c&&(e=c);for(var f=0;f'+w2utils.lang(h)+"\n"}return d}for(var b=this,c='',d=!1,e=0;eX",d=!0),null==f.inTag&&(f.inTag=""),null==f.outTag&&(f.outTag=""),null==f.style&&(f.style=""),null==f.type&&(f.type="text");var h='";switch(c+='"}}return c+='
    '+g+' '+(f.caption||"")+' '+h+' ',f.type){case"text":case"alphanumeric":case"hex":case"color":case"list":case"combo":case"enum":var i="width: 250px;";["hex","color"].indexOf(f.type)!=-1&&(i="width: 90px;"),c+='";break;case"int":case"float":case"money":case"currency":case"percent":case"date":case"time":case"datetime":var i="width: 90px";"datetime"==f.type&&(i="width: 140px;"),c+='";break;case"select":c+=''}c+=f.outTag+"
    "},initOperator:function(a,b){var c=this,d=c.searches[b],e=$("#grid_"+c.name+"_range_"+b),f=$("#grid_"+c.name+"_field_"+b),g=f.parent().find("span input");switch(f.show(),e.hide(),$(a).val()){case"between":e.show(),g.w2field(d.type,d.options);break;case"not null":case"null":f.hide(),f.val("1"),f.change()}},initSearches:function(){for(var a=this,b=0;b'+l+""}else i+='"}$("#grid_"+this.name+"_field_"+b).html(i)}null!=d?("int"==d.type&&["in","not in"].indexOf(d.operator)!=-1&&$("#grid_"+this.name+"_field_"+b).w2field("clear").val(d.value),$("#grid_"+this.name+"_operator_"+b).val(d.operator).trigger("change"),$.isArray(d.value)?["in","not in"].indexOf(d.operator)!=-1?$("#grid_"+this.name+"_field_"+b).val(d.value).trigger("change"):($("#grid_"+this.name+"_field_"+b).val(d.value[0]).trigger("change"),$("#grid_"+this.name+"_field2_"+b).val(d.value[1]).trigger("change")):null!=d.value&&$("#grid_"+this.name+"_field_"+b).val(d.value).trigger("change")):$("#grid_"+this.name+"_operator_"+b).val(f).trigger("change")}$("#w2ui-overlay-"+this.name+"-searchOverlay .w2ui-grid-searches *[rel=search]").on("keypress",function(b){13==b.keyCode&&(a.search(),$().w2overlay({name:a.name+"-searchOverlay"}))})},getColumnsHTML:function(){function a(){var a="",b="",d="";""!=c.columnGroups[c.columnGroups.length-1].caption&&c.columnGroups.push({caption:""}),c.show.lineNumbers&&(a+='
     
    '),c.show.selectColumn&&(a+='
     
    '),c.show.expandColumn&&(a+='
     
    ');var e=0;b+='';for(var f=0;f'),d='"+m+'
    '+(h.caption?h.caption:" ")+"
    ",h&&h.frozen?a+=d:b+=d}else d='
    '+(g.caption?g.caption:" ")+"
    ",h&&h.frozen?a+=d:b+=d;e+=g.span}return a+="",b+='',[a,b]}function b(a){var b="",d="";c.show.lineNumbers&&(b+='
    #
    "),c.show.selectColumn&&(b+='
    "),c.show.expandColumn&&(b+='
     
    ');var e,f=0,g=0;d+='';for(var h=0;hc.last.colEnd)||i.frozen)&&!i.hidden&&(e.master!==!0||a)){var j=c.getColumnCellHTML(h);i&&i.frozen?b+=j:d+=j}}return b+='
     
    ',d+='
     
    ',b+="",d+="",[b,d]}var c=this,d="",e="";if(this.show.columnHeaders)if(this.columnGroups.length>0){var f=b(!0),g=a(),h=b(!1);d=f[0]+g[0]+h[0],e=f[1]+g[1]+h[1]}else{var i=b(!0);d=i[0],e=i[1]}return[d,e]},getColumnCellHTML:function(a){var b=this.columns[a];if(null==b)return""; +for(var c=!this.reorderColumns||this.columnGroups&&this.columnGroups.length?"":" w2ui-reorder-cols-head ",d="",e=0;e"+(b.resizable!==!1?'
    ':"")+'
    '+(b.caption?b.caption:" ")+"
    ";return i},columnTooltipShow:function(a){if("normal"!=this.columnTooltip){var b=$(this.box).find("#grid_"+this.name+"_column_"+a),c=this.columns[a],d=this.columnTooltip;b.prop("_mouse_over",!0),setTimeout(function(){b.prop("_mouse_over")===!0&&b.prop("_mouse_tooltip")!==!0&&(b.prop("_mouse_tooltip",!0),b.w2tag(c.tooltip,{position:d}))},1)}},columnTooltipHide:function(a){if("normal"!=this.columnTooltip){var b=$(this.box).find("#grid_"+this.name+"_column_"+a);this.columns[a];b.removeProp("_mouse_over"),setTimeout(function(){b.prop("_mouse_over")!==!0&&b.prop("_mouse_tooltip")===!0&&(b.removeProp("_mouse_tooltip"),b.w2tag())},1)}},getRecordsHTML:function(){var a=this.records.length,b="object"!=typeof this.url?this.url:this.url.get;0==this.searchData.length||b||(a=this.last.searchIds.length),a>this.vs_start?this.last.show_extra=this.vs_extra:this.last.show_extra=this.vs_start;var c=$("#grid_"+this.name+"_records"),d=Math.floor(c.height()/this.recordHeight)+this.last.show_extra+1;(!this.fixedBody||d>a)&&(d=a);var e=this.getRecordHTML(-1,0),f=""+e[0],g="
    "+e[1];f+='',g+='';for(var h=0;h
    ',g+=' ',this.last.range_start=0,this.last.range_end=d,[f,g]},getSummaryHTML:function(){if(0!==this.summary.length){for(var a=this.getRecordHTML(-1,0),b=""+a[0],c="
    "+a[1],d=0;d0&&$(c.box).find(".w2ui-grid-data > div").w2marker(a)},50))}var c=((new Date).getTime(),this),d="object"!=typeof this.url?this.url:this.url.get,e=$("#grid_"+this.name+"_records"),f=$("#grid_"+this.name+"_frecords");if(a){var g=a.target.scrollTop,h=a.target.scrollLeft;c.last.scrollTop=g,c.last.scrollLeft=h,$("#grid_"+c.name+"_columns")[0].scrollLeft=h,$("#grid_"+c.name+"_summary")[0].scrollLeft=h,f[0].scrollTop=g}this.last.bubbleEl&&($(this.last.bubbleEl).w2tag(),this.last.bubbleEl=null);var i=null,j=null;if(c.disableCVS||c.columnGroups.length>0)i=0,j=c.columns.length-1;else{for(var k=e.width(),l=0,m=0;mc.last.scrollLeft&&null==i&&(i=m),l+n-30>c.last.scrollLeft+k&&null==j&&(j=m),l+=n}null==j&&(j=c.columns.length-1)}if(null!=i&&(i<0&&(i=0),j<0&&(j=0),i==j&&(i>0?i--:j++),i!=c.last.colStart||j!=c.last.colEnd)){var o=$(c.box),p=Math.abs(i-c.last.colStart),q=Math.abs(j-c.last.colEnd);if(p<5&&q<5){var r=o.find(".w2ui-grid-columns #grid_"+c.name+"_column_start"),s=o.find(".w2ui-grid-columns .w2ui-head-last"),t=o.find("#grid_"+c.name+"_records .w2ui-grid-data-spacer"),u=o.find("#grid_"+c.name+"_records .w2ui-grid-data-last"),v=o.find("#grid_"+c.name+"_summary .w2ui-grid-data-spacer"),w=o.find("#grid_"+c.name+"_summary .w2ui-grid-data-last");if(i>c.last.colStart)for(var m=c.last.colStart;mj;m--)o.find("#grid_"+c.name+"_columns #grid_"+c.name+"_column_"+m).remove(),o.find("#grid_"+c.name+'_records td[col="'+m+'"]').remove(),o.find("#grid_"+c.name+'_summary td[col="'+m+'"]').remove();if(i=i;m--)c.columns[m]&&(c.columns[m].frozen||c.columns[m].hidden)||(r.after(c.getColumnCellHTML(m)),t.each(function(a,b){var d=$(b).parent().attr("index"),e='';null!=d&&(e=c.getCellHTML(parseInt(d),m,!1)),$(b).after(e)}),v.each(function(a,b){var d=$(b).parent().attr("index"),e='';null!=d&&(e=c.getCellHTML(parseInt(d),m,!0)),$(b).after(e)}));if(j>c.last.colEnd)for(var m=c.last.colEnd+1;m<=j;m++)c.columns[m]&&(c.columns[m].frozen||c.columns[m].hidden)||(s.before(c.getColumnCellHTML(m)),u.each(function(a,b){var d=$(b).parent().attr("index"),e='';null!=d&&(e=c.getCellHTML(parseInt(d),m,!1)),$(b).before(e)}),w.each(function(a,b){var d=$(b).parent().attr("index"),e=c.getCellHTML(parseInt(d),m,!0);$(b).before(e)}));c.last.colStart=i,c.last.colEnd=j,c.resizeRecords()}else{c.last.colStart=i,c.last.colEnd=j;var x=this.getColumnsHTML(),y=this.getRecordsHTML(),z=this.getSummaryHTML(),A=o.find("#grid_"+this.name+"_columns"),B=o.find("#grid_"+this.name+"_records"),C=o.find("#grid_"+this.name+"_frecords"),D=o.find("#grid_"+this.name+"_summary");A.find("tbody").html(x[1]),C.html(y[0]),B.prepend(y[1]),null!=z&&D.html(z[1]),setTimeout(function(){B.find("> table").not("table:first-child").remove(),D[0]&&(D[0].scrollLeft=c.last.scrollLeft)},1),c.resizeRecords()}}var E=this.records.length;if(0==this.searchData.length||d||(E=this.last.searchIds.length),0!==E&&0!==e.length&&0!==e.height()&&(E>this.vs_start?this.last.show_extra=this.vs_extra:this.last.show_extra=this.vs_start,!(e.height()E&&(F=E),G>=E-1&&(G=E),$("#grid_"+this.name+"_footer .w2ui-footer-right").html((c.show.statusRange?w2utils.formatNumber(this.offset+F)+"-"+w2utils.formatNumber(this.offset+G)+(this.total!=-1?" "+w2utils.lang("of")+" "+w2utils.formatNumber(this.total):""):"")+(d&&c.show.statusBuffered?" ("+w2utils.lang("buffered")+" "+w2utils.formatNumber(E)+(this.offset>0?", skip "+w2utils.formatNumber(this.offset):"")+")":"")),d||this.fixedBody&&!(this.total!=-1&&this.total<=this.vs_start)){var H=Math.floor(e[0].scrollTop/this.recordHeight)-this.last.show_extra,I=H+Math.floor(e.height()/this.recordHeight)+2*this.last.show_extra+1;H<1&&(H=1),I>this.total&&this.total!=-1&&(I=this.total);var J=e.find("#grid_"+this.name+"_rec_top"),K=e.find("#grid_"+this.name+"_rec_bottom"),L=f.find("#grid_"+this.name+"_frec_top"),M=f.find("#grid_"+this.name+"_frec_bottom");String(J.next().prop("id")).indexOf("_expanded_row")!=-1&&(J.next().remove(),L.next().remove()),this.total>I&&String(K.prev().prop("id")).indexOf("_expanded_row")!=-1&&(K.prev().remove(),M.prev().remove());var N=parseInt(J.next().attr("line")),O=parseInt(K.prev().attr("line"));if(N=N-this.last.show_extra+2&&H>1)return;for(;;){var P=f.find("#grid_"+this.name+"_frec_bottom").prev(),Q=e.find("#grid_"+this.name+"_rec_bottom").prev();if("top"==Q.attr("line"))break;if(!(parseInt(Q.attr("line"))>I))break;P.remove(),Q.remove()}var R=e.find("#grid_"+this.name+"_rec_top").next(),S=R.attr("line");"bottom"==S&&(S=I);for(var m=parseInt(S)-1;m>=H;m--)if(this.records[m-1]){var Q=this.records[m-1].w2ui;Q&&!Array.isArray(Q.children)&&(Q.expanded=!1);var T=this.getRecordHTML(m-1,m);J.after(T[1]),L.after(T[0])}b(),setTimeout(function(){c.refreshRanges()},0)}var U=(H-1)*c.recordHeight,V=(E-I)*c.recordHeight;V<0&&(V=0),J.css("height",U+"px"),L.css("height",U+"px"),K.css("height",V+"px"),M.css("height",V+"px"),c.last.range_start=H,c.last.range_end=I;var W=Math.floor(e[0].scrollTop/this.recordHeight),X=W+Math.floor(e.height()/this.recordHeight);if(X+10>E&&this.last.pull_more!==!0&&(E
    ')}),(Y.find("td .w2ui-spinner").length>0||Y.find("td").text().indexOf("Load")==-1)&&Y.find("td").html("
    "+w2utils.lang("Load")+" "+c.limit+" "+w2utils.lang("More")+"...
    ")}E>=this.total-this.offset&&this.total!=-1&&$("#grid_"+this.name+"_rec_more, #grid_"+this.name+"_frec_more").hide()}}},getRecordHTML:function(a,b,c){var d,e="",f="",g="",h=this.last.selection;if(a==-1){f+='
    ',g+='',this.show.lineNumbers&&(f+=''),this.show.selectColumn&&(f+=''),this.show.expandColumn&&(f+=''),g+='';for(var i=0;i',j.frozen&&!j.hidden)f+=e;else{if(j.hidden||ithis.last.colEnd)continue;g+=e}}return f+='',g+='',f+="",g+="",[f,g]}var k="object"!=typeof this.url?this.url:this.url.get;if(c!==!0)if(this.searchData.length>0&&!k){if(a>=this.last.searchIds.length)return"";a=this.last.searchIds[a],d=this.records[a]}else{if(a>=this.records.length)return"";d=this.records[a]}else{if(a>=this.summary.length)return"";d=this.summary[a]}if(!d)return"";null==d.recid&&null!=this.recid&&null!=d[this.recid]&&(d.recid=d[this.recid]);var l=(w2utils.escapeId(d.recid),!1);h.indexes.indexOf(a)!=-1&&(l=!0);var m=d.w2ui?d.w2ui.style:"";null!=m&&"string"==typeof m||(m="");var n=d.w2ui?d.w2ui.class:"";if(null!=n&&"string"==typeof n||(n=""),f+='",g+='",this.show.lineNumbers&&(f+='"),this.show.selectColumn&&(f+='"),this.show.expandColumn){var o="";o=d.w2ui&&d.w2ui.expanded===!0?"-":"+",d.w2ui&&"none"==d.w2ui.expanded&&(o=""),d.w2ui&&"spinner"==d.w2ui.expanded&&(o='
    '),f+='"}g+='';for(var p=0,q=0;;){var r=1,j=this.columns[p];if(null==j)break;if(j.hidden)p++,q>0&&q--;else if(q>0){if(p++,null==this.columns[p])break;d.w2ui.colspan[this.columns[p-1].field]=0,q--}else{if(d.w2ui){var s=d.w2ui.colspan,t=this.columns[p].field;s&&0===s[t]&&delete s[t]}if(!(pthis.last.colEnd)||j.frozen){if(d.w2ui&&"object"==typeof d.w2ui.colspan){var u=parseInt(d.w2ui.colspan[j.field])||null;if(u>1){for(var v=0,i=p;i=this.columns.length);i++)this.columns[i].hidden&&v++;r=u-v,q=u-1}}var w=this.getCellHTML(a,p,c,r);j.frozen?f+=w:g+=w,p++}else p++}}return f+='',g+='',f+="",g+="",[f,g]},getLineHTML:function(a){return"
    "+a+"
    "},getCellHTML:function(a,b,c,d){var e=this.columns[b];if(null==e)return"";var f=c!==!0?this.records[a]:this.summary[a],g=this.getCellValue(a,b,c),h=this.getCellEditable(a,b),i="max-height: "+parseInt(this.recordHeight)+"px;",j=!c&&f&&f.w2ui&&f.w2ui.changes&&null!=f.w2ui.changes[e.field],k="",l="",m=this.last.selection,n=!1,o="";if(m.indexes.indexOf(a)!=-1&&(n=!0),null==d&&(d=f&&f.w2ui&&f.w2ui.colspan&&f.w2ui.colspan[e.field]?f.w2ui.colspan[e.field]:1),0===b&&f&&f.w2ui&&Array.isArray(f.w2ui.children)){for(var p=0,q=this.get(f.w2ui.parent_recid,!0);;){if(null==q)break;p++;var r=this.records[q].w2ui;if(null==r||null==r.parent_recid)break;q=this.get(r.parent_recid,!0)}if(f.w2ui.parent_recid)for(var s=0;s';o+='"}if(e.info===!0&&(e.info={}),null!=e.info&&(e.info.icon||(e.info.icon="w2ui-icon-info"),o+=''),null!=e.render){if("function"==typeof e.render&&(g=$.trim(e.render.call(this,f,a,b,g)),(g.length<4||"'+o+String(g)+"")),"object"==typeof e.render&&(g='
    '+o+(e.render[g]||"")+"
    "),"string"==typeof e.render){var t=e.render.toLowerCase().indexOf(":"),r=[];t==-1?(r[0]=e.render.toLowerCase(),r[1]=""):(r[0]=e.render.toLowerCase().substr(0,t),r[1]=e.render.toLowerCase().substr(t+1));var u=w2utils.formatters[r[0]];g='
    '+o+("function"==typeof u?u(g,r[1]):"")+"
    "}}else{if(h&&["checkbox","check"].indexOf(h.type)!=-1){var v=c?-(a+1):a;i+="text-align: center;",g='',o=""}if(this.show.recordTitles){var w=w2utils.stripTags(String(g).replace(/"/g,"''"));null!=e.title&&("function"==typeof e.title&&(w=e.title.call(this,f,a,b)),"string"==typeof e.title&&(w=e.title))}g='
    '+o+String(g)+"
    "}if(null==g&&(g=""),"string"==typeof e.render){var r=e.render.toLowerCase().split(":");["number","int","float","money","currency","percent","size"].indexOf(r[0])!=-1&&(k+="text-align: right;")}f&&f.w2ui&&("object"==typeof f.w2ui.style&&("string"==typeof f.w2ui.style[b]&&(k+=f.w2ui.style[b]+";"),"string"==typeof f.w2ui.style[e.field]&&(k+=f.w2ui.style[e.field]+";")),"object"==typeof f.w2ui.class&&("string"==typeof f.w2ui.class[b]&&(l+=f.w2ui.class[b]+" "),"string"==typeof f.w2ui.class[e.field]&&(l+=f.w2ui.class[e.field]+" ")));var x=!1;return n&&$.inArray(b,m.columns[a])!=-1&&(x=!0),g='
    "},showBubble:function(a,b){var c="",d=this.columns[b].info,e=this.records[a],f=$(this.box).find("#grid_"+this.name+"_data_"+a+"_"+b+" .w2ui-info");if(this.last.bubbleEl&&$(this.last.bubbleEl).w2tag(),this.last.bubbleEl=f,null==d.fields){d.fields=[];for(var g=0;g1&&(w2utils.formatters[j[1]]?k=w2utils.formatters[j[1]](k,j[2]||null):console.log('ERROR: w2utils.formatters["'+j[1]+'"] does not exists.')),(d.showEmpty===!0||null!=k&&""!=k)&&(null!=d.maxLength&&"string"==typeof k&&k.length>d.maxLength&&(k=k.substr(0,d.maxLength)+"..."),c+="")}else c+=''}c+="
    "+(c!==!0?this.getLineHTML(b,d):"")+"'+(c!==!0?'
    ':"")+"
    '+(c!==!0?'
    "+o+"
    ":"")+"
    1?'colspan="'+d+'"':"")+">"+g+"
    "+h.caption+""+((0===k?"0":k)||"")+"
    "}else if($.isPlainObject(i)){c='';for(var l in i){var m=i[l];if(""!=m&&"-"!=m&&"--"!=m&&"---"!=m){var j=String(m).split(":"),h=this.getColumn(j[0]);null==h&&(h={field:j[0],caption:j[0]});var k=h?this.parseField(e,h.field):"";j.length>1&&(w2utils.formatters[j[1]]?k=w2utils.formatters[j[1]](k,j[2]||null):console.log('ERROR: w2utils.formatters["'+j[1]+'"] does not exists.')),"function"==typeof m&&(k=m(e,a,b)),(d.showEmpty===!0||null!=k&&""!=k)&&(null!=d.maxLength&&"string"==typeof k&&k.length>d.maxLength&&(k=k.substr(0,d.maxLength)+"..."),c+="")}else c+=''}c+="
    "+l+""+(k||"")+"
    "}$(f).w2tag($.extend({html:c,left:-4,position:"bottom|top",className:"w2ui-info-bubble",style:"",hideOnClick:!0},d.options||{}))},getCellEditable:function(a,b){var c=this.columns[b],d=this.records[a];if(!d||!c)return null;var e=d.w2ui?d.w2ui.editable:null;if(e===!1)return null;if((null==e||e===!0)&&(e=c?c.editable:null,"function"==typeof e)){var f=this.getCellValue(a,b,!1);e=e.call(this,d,a,b,f)}return e},getCellValue:function(a,b,c){var d=this.columns[b],e=c!==!0?this.records[a]:this.summary[a],f=this.parseField(e,d.field);return e&&e.w2ui&&e.w2ui.changes&&null!=e.w2ui.changes[d.field]&&(f=e.w2ui.changes[d.field]),$.isPlainObject(f)&&d.editable&&(null!=f.text&&(f=f.text),null!=f.id&&(f=f.id)),null==f&&(f=""),f},getFooterHTML:function(){return'
    '},status:function(a){if(null!=a)$("#grid_"+this.name+"_footer").find(".w2ui-footer-left").html(a);else{var b="",c=this.getSelection();if(c.length>0&&(this.show.statusSelection&&c.length>1&&(b=String(c.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,")+" "+w2utils.lang("selected")),this.show.statusRecordID&&1==c.length)){var d=c[0];"object"==typeof d&&(d=d.recid+", "+w2utils.lang("Column")+": "+d.column),b=w2utils.lang("Record ID")+": "+d+" "}$("#grid_"+this.name+"_footer .w2ui-footer-left").html(b),1==c.length?this.toolbar.enable("w2ui-edit"):this.toolbar.disable("w2ui-edit"),c.length>=1?this.toolbar.enable("w2ui-delete"):this.toolbar.disable("w2ui-delete")}},lock:function(a,b){var c=this,d=Array.prototype.slice.call(arguments,0);d.unshift(this.box),setTimeout(function(){$(c.box).find("#grid_"+c.name+"_empty_msg").remove(),w2utils.lock.apply(window,d)},10)},unlock:function(a){var b=this.box;setTimeout(function(){$(b).find(".w2ui-message").not(".w2ui-closing").length>0||w2utils.unlock(b,a)},25)},stateSave:function(a){if(!w2utils.hasLocalStorage)return null;for(var b={columns:[],show:$.extend({},this.show),last:{search:this.last.search,multi:this.last.multi,logic:this.last.logic,caption:this.last.caption,field:this.last.field,scrollTop:this.last.scrollTop,scrollLeft:this.last.scrollLeft},sortData:[],searchData:[]},c=0;c0&&b.localSort(),b.searchData.length>0&&b.localSearch()),b.last.scrollTop=f,b.last.scrollLeft=g,b.refresh()},1)}return this.trigger($.extend(e,{phase:"after"})),!0},stateReset:function(){if(this.stateRestore(this.last.state),w2utils.hasLocalStorage)try{var a=$.parseJSON(localStorage.w2ui||"{}");a.states&&a.states[this.stateId||this.name]&&delete a.states[this.stateId||this.name],localStorage.w2ui=JSON.stringify(a)}catch(a){return delete localStorage.w2ui,null}},parseField:function(a,b){var c="";try{c=a;for(var d=String(b).split("."),e=0;e=this.columns.length)return null;var e=this.records[a].w2ui,f=(this.columns[b],this.columns[d]),g=e&&e.colspan&&!isNaN(e.colspan[f.field])?parseInt(e.colspan[f.field]):1;if(null==f)return null;if(f&&f.hidden||0===g)return this.nextCell(a,d,c);if(c){var h=this.getCellEditable(a,b);if(null==h||["checkbox","check"].indexOf(h.type)!=-1)return this.nextCell(a,d,c)}return d},prevCell:function(a,b,c){var d=b-1;if(d<0)return null;var e=this.records[a].w2ui,f=this.columns[d],g=e&&e.colspan&&!isNaN(e.colspan[f.field])?parseInt(e.colspan[f.field]):1;if(null==f)return null;if(f&&f.hidden||0===g)return this.prevCell(a,d,c);if(c){var h=this.getCellEditable(a,b);if(null==h||["checkbox","check"].indexOf(h.type)!=-1)return this.prevCell(a,d,c)}return d},nextRow:function(a,b){var c=this.last.searchIds,d=null;if(a+10&&a0)for(;;){if($.inArray(a,c)!=-1||a>this.records.length)break;a++}var e=this.records[a].w2ui,f=this.columns[b],g=e&&e.colspan&&null!=f&&!isNaN(e.colspan[f.field])?parseInt(e.colspan[f.field]):1;d=0===g?this.nextRow(a,b):a}return d},prevRow:function(a,b){var c=this.last.searchIds,d=null;if(a>0&&0===c.length||c.length>0&&a>c[0]){if(a--,c.length>0)for(;;){if($.inArray(a,c)!=-1||a<0)break;a--}var e=this.records[a].w2ui,f=this.columns[b],g=e&&e.colspan&&null!=f&&!isNaN(e.colspan[f.field])?parseInt(e.colspan[f.field]):1;d=0===g?this.prevRow(a,b):a}return d},selectionSave:function(){return this.last._selection=this.getSelection(),this.last._selection},selectionRestore:function(a){var b=(new Date).getTime();this.last.selection={indexes:[],columns:{}};for(var c=this.last.selection,d=this.last._selection,e=0;e'+a+"",buttons:'",onOpen:function(a){setTimeout(function(){$(this.box).find(".w2ui-btn").focus()},25)},onClose:function(a){"function"==typeof b&&b()}}),w2utils.message.call(this,{box:this.box,path:"w2ui."+this.name,title:".w2ui-grid-header:visible",body:".w2ui-grid-box"},a)}},$.extend(w2grid.prototype,w2utils.event),w2obj.grid=w2grid}(jQuery),function(a){var b=function(b){this.box=null,this.name=null,this.panels=[],this.tmp={},this.padding=1,this.resizer=4,this.style="",a.extend(!0,this,w2obj.layout,b)},c=["top","left","main","preview","right","bottom"];a.fn.w2layout=function(d){function e(b,c,d){var e=b.get(c);return null!=e&&null==d&&(d=e.tabs),null!=e&&null!=d&&(a.isArray(d)&&(d={tabs:d}),a().w2destroy(b.name+"_"+c+"_tabs"),e.tabs=a().w2tabs(a.extend({},d,{owner:b,name:b.name+"_"+c+"_tabs"})),e.show.tabs=!0,!0)}function f(b,c,d){var e=b.get(c);return null!=e&&null==d&&(d=e.toolbar),null!=e&&null!=d&&(a.isArray(d)&&(d={items:d}),a().w2destroy(b.name+"_"+c+"_toolbar"),e.toolbar=a().w2toolbar(a.extend({},d,{owner:b,name:b.name+"_"+c+"_toolbar"})),e.show.toolbar=!0,!0)}if(a.isPlainObject(d)){if(!w2utils.checkName(d,"w2layout"))return;var g=d.panels||[],h=new b(d);a.extend(h,{handlers:[],panels:[]});for(var i=0,j=g.length;i0&&h.render(a(this)[0]),w2ui[h.name]=h,h}var l=w2ui[a(this).attr("name")];return l?arguments.length>0?(l[d]&&l[d].apply(l,Array.prototype.slice.call(arguments,1)),this):l:null},b.prototype={onShow:null,onHide:null,onResizing:null,onResizerClick:null,onRender:null,onRefresh:null,onContent:null, +onResize:null,onDestroy:null,panel:{type:null,title:"",size:100,minSize:20,maxSize:!1,hidden:!1,resizable:!1,overflow:"auto",style:"",content:"",tabs:null,toolbar:null,width:null,height:null,show:{toolbar:!1,tabs:!1},onRefresh:null,onShow:null,onHide:null},html:function(a,b,c){return this.content(a,b,c)},content:function(b,c,d){var e=this,f=this.get(b);if("css"==b)return a("#layout_"+e.name+"_panel_css").html(""),!0;if(null==f)return!1;if(null==c)return f.content;var g=this.trigger({phase:"before",type:"content",target:b,object:f,content:c,transition:d});if(g.isCancelled!==!0){if(c instanceof jQuery)return console.log("ERROR: You can not pass jQuery object to w2layout.content() method"),!1;var h="#layout_"+this.name+"_panel_"+f.type,i=a(h+"> .w2ui-panel-content"),j=0;if(i.length>0&&(a(h).scrollTop(0),j=a(i).position().top),""===f.content)f.content=c,this.refresh(b);else{if(f.content=c,!f.hidden&&null!=d&&""!==d){var k=a(h+"> .w2ui-panel-content");k.after('
    ');var l=a(h+"> .w2ui-panel-content.new-panel");k.css("top",j),l.css("top",j),"object"==typeof c?(c.box=l[0],c.render()):l.html(c),w2utils.transition(k[0],l[0],d,function(){k.remove(),l.removeClass("new-panel"),l.css("overflow",f.overflow),e.resize(),window.navigator.userAgent.indexOf("MSIE")!=-1&&setTimeout(function(){e.resize()},100)})}this.refresh(b)}return e.trigger(a.extend(g,{phase:"after"})),e.resize(),window.navigator.userAgent.indexOf("MSIE")!=-1&&setTimeout(function(){e.resize()},100),!0}},message:function(b,c){var d=this;"string"==typeof c&&(c={width:c.length<300?350:550,height:c.length<300?170:250,body:'
    '+c+"
    ",buttons:'",onOpen:function(b){setTimeout(function(){a(this.box).find(".w2ui-btn").focus()},25)}});var e,f=this.get(b),g=a("#layout_"+this.name+"_panel_"+f.type),h=g.css("overflow");c&&(c.onClose&&(e=c.onClose),c.onClose=function(b){"function"==typeof e&&e(b),b.done(function(){a("#layout_"+d.name+"_panel_"+f.type).css("overflow",h)})}),a("#layout_"+this.name+"_panel_"+f.type).css("overflow","hidden"),w2utils.message.call(this,{box:a("#layout_"+this.name+"_panel_"+f.type),param:b,path:"w2ui."+this.name,title:".w2ui-panel-title:visible",body:".w2ui-panel-content"},c)},load:function(b,c,d,e){var f=this;return"css"==b?(a.get(c,function(a,c,d){f.content(b,d.responseText),e&&e()}),!0):null!=this.get(b)&&(a.get(c,function(a,c,g){f.content(b,g.responseText,d),e&&e(),f.resize(),window.navigator.userAgent.indexOf("MSIE")!=-1&&setTimeout(function(){f.resize()},100)}),!0)},sizeTo:function(b,c,d){var e=this,f=e.get(b);return null!=f&&(a(e.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition",d!==!0?".2s":"0s")),setTimeout(function(){e.set(b,{size:c})},1),setTimeout(function(){a(e.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition","0s")),e.resize()},500),!0)},show:function(b,c){var d=this,e=this.trigger({phase:"before",type:"show",target:b,object:this.get(b),immediate:c});if(e.isCancelled!==!0){var f=d.get(b);return null!=f&&(f.hidden=!1,c===!0?(a("#layout_"+d.name+"_panel_"+b).css({opacity:"1"}),d.trigger(a.extend(e,{phase:"after"})),d.resize()):(a("#layout_"+d.name+"_panel_"+b).css({opacity:"0"}),a(d.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition",".2s")),setTimeout(function(){d.resize()},1),setTimeout(function(){a("#layout_"+d.name+"_panel_"+b).css({opacity:"1"})},250),setTimeout(function(){a(d.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition","0s")),d.trigger(a.extend(e,{phase:"after"})),d.resize()},500)),!0)}},hide:function(b,c){var d=this,e=this.trigger({phase:"before",type:"hide",target:b,object:this.get(b),immediate:c});if(e.isCancelled!==!0){var f=d.get(b);return null!=f&&(f.hidden=!0,c===!0?(a("#layout_"+d.name+"_panel_"+b).css({opacity:"0"}),d.trigger(a.extend(e,{phase:"after"})),d.resize()):(a(d.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition",".2s")),a("#layout_"+d.name+"_panel_"+b).css({opacity:"0"}),setTimeout(function(){d.resize()},1),setTimeout(function(){a(d.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition","0s")),d.trigger(a.extend(e,{phase:"after"})),d.resize()},500)),!0)}},toggle:function(a,b){var c=this.get(a);return null!=c&&(c.hidden?this.show(a,b):this.hide(a,b))},set:function(b,c){var d=this.get(b,!0);return null!=d&&(a.extend(this.panels[d],c),null==c.content&&null==c.resizable||this.refresh(b),this.resize(),!0)},get:function(a,b){for(var c=0;c .w2ui-panel-content");return 1!=c.length?null:c[0]},hideToolbar:function(b){var c=this.get(b);c&&(c.show.toolbar=!1,a("#layout_"+this.name+"_panel_"+b+"> .w2ui-panel-toolbar").hide(),this.resize())},showToolbar:function(b){var c=this.get(b);c&&(c.show.toolbar=!0,a("#layout_"+this.name+"_panel_"+b+"> .w2ui-panel-toolbar").show(),this.resize())},toggleToolbar:function(a){var b=this.get(a);b&&(b.show.toolbar?this.hideToolbar(a):this.showToolbar(a))},assignToolbar:function(b,c){"string"==typeof c&&null!=w2ui[c]&&(c=w2ui[c]);var d=this.get(b);d.toolbar=c;var e=a(this.box).find(b+"> .w2ui-panel-toolbar");null!=d.toolbar?(0===e.find("[name="+d.toolbar.name+"]").length?e.w2render(d.toolbar):null!=d.toolbar&&d.toolbar.refresh(),this.showToolbar(b),this.refresh("main")):(e.html(""),this.hideToolbar(b))},hideTabs:function(b){var c=this.get(b);c&&(c.show.tabs=!1,a("#layout_"+this.name+"_panel_"+b+"> .w2ui-panel-tabs").hide(),this.resize())},showTabs:function(b){var c=this.get(b);c&&(c.show.tabs=!0,a("#layout_"+this.name+"_panel_"+b+"> .w2ui-panel-tabs").show(),this.resize())},toggleTabs:function(a){var b=this.get(a);b&&(b.show.tabs?this.hideTabs(a):this.showTabs(a))},render:function(b){function d(){h.tmp.events={resize:function(a){w2ui[h.name].resize()},resizeStart:e,mouseMove:g,mouseUp:f},a(window).on("resize",h.tmp.events.resize)}function e(b,d){if(h.box){d||(d=window.event),a(document).off("mousemove",h.tmp.events.mouseMove).on("mousemove",h.tmp.events.mouseMove),a(document).off("mouseup",h.tmp.events.mouseUp).on("mouseup",h.tmp.events.mouseUp),h.tmp.resize={type:b,x:d.screenX,y:d.screenY,diff_x:0,diff_y:0,value:0};for(var e=0;e0?f.attr("locked","previous"):h.lock(c[e],{opacity:0})}"left"!=b&&"right"!=b||(h.tmp.resize.value=parseInt(a("#layout_"+h.name+"_resizer_"+b)[0].style.left)),"top"!=b&&"preview"!=b&&"bottom"!=b||(h.tmp.resize.value=parseInt(a("#layout_"+h.name+"_resizer_"+b)[0].style.top))}}function f(b){if(h.box&&(b||(b=window.event),a(document).off("mousemove",h.tmp.events.mouseMove),a(document).off("mouseup",h.tmp.events.mouseUp),null!=h.tmp.resize)){for(var d=0;dc.width&&(g=c.minSize-c.width),c.maxSize&&c.width+g>c.maxSize&&(g=c.maxSize-c.width),j.minSize+g>j.width&&(g=j.width-j.minSize);break;case"right":c.minSize+g>c.width&&(g=c.width-c.minSize),c.maxSize&&c.width-g>c.maxSize&&(g=c.width-c.maxSize),j.minSize-g>j.width&&(g=j.minSize-j.width);break;case"top":c.minSize-i>c.height&&(i=c.minSize-c.height),c.maxSize&&c.height+i>c.maxSize&&(i=c.maxSize-c.height),j.minSize+i>j.height&&(i=j.height-j.minSize);break;case"preview":case"bottom":c.minSize+i>c.height&&(i=c.height-c.minSize),c.maxSize&&c.height-i>c.maxSize&&(i=c.height-c.maxSize),j.minSize-i>j.height&&(i=j.minSize-j.height)}switch(d.diff_x=g,d.diff_y=i,d.type){case"top":case"preview":case"bottom":d.diff_x=0,f.length>0&&(f[0].style.top=d.value+d.diff_y+"px");break;case"left":case"right":d.diff_y=0,f.length>0&&(f[0].style.left=d.value+d.diff_x+"px")}h.trigger(a.extend(e,{phase:"after"}))}}}var h=this,i=(new Date).getTime(),j=h.trigger({phase:"before",type:"render",target:h.name,box:b});if(j.isCancelled!==!0){if(null!=b&&(a(h.box).find("#layout_"+h.name+"_panel_main").length>0&&a(h.box).removeAttr("name").removeClass("w2ui-layout").html(""),h.box=b),!h.box)return!1;a(h.box).attr("name",h.name).addClass("w2ui-layout").html("
    "),a(h.box).length>0&&(a(h.box)[0].style.cssText+=h.style);for(var k=0;k
    ');a(h.box).find(" > div").append(l)}return a(h.box).find(" > div").append('
    '),h.refresh(),h.trigger(a.extend(j,{phase:"after"})),setTimeout(function(){d(),h.resize()},0),(new Date).getTime()-i}},refresh:function(b){var c=this;null==b&&(b=null);var d=(new Date).getTime(),e=c.trigger({phase:"before",type:"refresh",target:null!=b?b:c.name,object:c.get(b)});if(e.isCancelled!==!0){if("string"==typeof b){var f=c.get(b);if(null==f)return;var g="#layout_"+c.name+"_panel_"+f.type,h="#layout_"+c.name+"_resizer_"+f.type;a(g).css({display:f.hidden?"none":"block"}),f.resizable?a(h).show():a(h).hide(),"object"==typeof f.content&&"function"==typeof f.content.render?(f.content.box=a(g+"> .w2ui-panel-content")[0],setTimeout(function(){a(g+"> .w2ui-panel-content").length>0&&(a(g+"> .w2ui-panel-content").removeClass().removeAttr("name").addClass("w2ui-panel-content").css("overflow",f.overflow)[0].style.cssText+=";"+f.style),f.content&&"function"==typeof f.content.render&&f.content.render()},1)):a(g+"> .w2ui-panel-content").length>0&&(a(g+"> .w2ui-panel-content").removeClass().removeAttr("name").addClass("w2ui-panel-content").html(f.content).css("overflow",f.overflow)[0].style.cssText+=";"+f.style);var i=a(c.box).find(g+"> .w2ui-panel-tabs");f.show.tabs?0===i.find("[name="+f.tabs.name+"]").length&&null!=f.tabs?i.w2render(f.tabs):f.tabs.refresh():i.html("").removeClass("w2ui-tabs").hide(),i=a(c.box).find(g+"> .w2ui-panel-toolbar"),f.show.toolbar?0===i.find("[name="+f.toolbar.name+"]").length&&null!=f.toolbar?i.w2render(f.toolbar):f.toolbar.refresh():i.html("").removeClass("w2ui-toolbar").hide(),i=a(c.box).find(g+"> .w2ui-panel-title"),f.title?i.html(f.title).show():i.html("").hide()}else{if(0===a("#layout_"+c.name+"_panel_main").length)return void c.render();c.resize();for(var j=0;j div").css({width:f+"px",height:g+"px"});for(var h,i,j,k,l,m=this,n=this.get("main"),o=this.get("preview"),p=this.get("left"),q=this.get("right"),r=this.get("top"),s=this.get("bottom"),t=null!=o&&o.hidden!==!0,u=null!=p&&p.hidden!==!0,v=null!=q&&q.hidden!==!0,w=null!=r&&r.hidden!==!0,x=null!=s&&s.hidden!==!0,y=0;ythis.padding?this.resizer:this.padding,a("#layout_"+this.name+"_resizer_top").show().css({display:"block",left:h+"px",top:i+"px",width:j+"px",height:k+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(b){var c=m.trigger({phase:"before",type:"resizerClick",target:"top",originalEvent:b});if(c.isCancelled!==!0)return w2ui[m.name].tmp.events.resizeStart("top",b),m.trigger(a.extend(c,{phase:"after"})),!1}))):(a("#layout_"+this.name+"_panel_top").hide(),a("#layout_"+this.name+"_resizer_top").hide()),null!=p&&p.hidden!==!0?(h=0,i=0+(w?r.sizeCalculated+this.padding:0),j=p.sizeCalculated,k=g-(w?r.sizeCalculated+this.padding:0)-(x?s.sizeCalculated+this.padding:0),l=a("#layout_"+this.name+"_panel_left"),window.navigator.userAgent.indexOf("MSIE")!=-1&&l.length>0&&l[0].clientHeightthis.padding?this.resizer:this.padding,a("#layout_"+this.name+"_resizer_left").show().css({display:"block",left:h+"px",top:i+"px",width:j+"px",height:k+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(b){var c=m.trigger({phase:"before",type:"resizerClick",target:"left",originalEvent:b});if(c.isCancelled!==!0)return w2ui[m.name].tmp.events.resizeStart("left",b),m.trigger(a.extend(c,{phase:"after"})),!1}))):(a("#layout_"+this.name+"_panel_left").hide(),a("#layout_"+this.name+"_resizer_left").hide()),null!=q&&q.hidden!==!0?(h=f-q.sizeCalculated,i=0+(w?r.sizeCalculated+this.padding:0),j=q.sizeCalculated,k=g-(w?r.sizeCalculated+this.padding:0)-(x?s.sizeCalculated+this.padding:0),a("#layout_"+this.name+"_panel_right").css({display:"block",left:h+"px",top:i+"px",width:j+"px",height:k+"px"}).show(),q.width=j,q.height=k,q.resizable&&(h-=this.padding,j=this.resizer>this.padding?this.resizer:this.padding,a("#layout_"+this.name+"_resizer_right").show().css({display:"block",left:h+"px",top:i+"px",width:j+"px",height:k+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(b){var c=m.trigger({phase:"before",type:"resizerClick",target:"right",originalEvent:b});if(c.isCancelled!==!0)return w2ui[m.name].tmp.events.resizeStart("right",b),m.trigger(a.extend(c,{phase:"after"})),!1}))):(a("#layout_"+this.name+"_panel_right").hide(),a("#layout_"+this.name+"_resizer_right").hide()),null!=s&&s.hidden!==!0?(h=0,i=g-s.sizeCalculated,j=f,k=s.sizeCalculated,a("#layout_"+this.name+"_panel_bottom").css({display:"block",left:h+"px",top:i+"px",width:j+"px",height:k+"px"}).show(),s.width=j,s.height=k,s.resizable&&(i-=0===this.padding?0:this.padding,k=this.resizer>this.padding?this.resizer:this.padding,a("#layout_"+this.name+"_resizer_bottom").show().css({display:"block",left:h+"px",top:i+"px",width:j+"px",height:k+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(b){var c=m.trigger({phase:"before",type:"resizerClick",target:"bottom",originalEvent:b});if(c.isCancelled!==!0)return w2ui[m.name].tmp.events.resizeStart("bottom",b),m.trigger(a.extend(c,{phase:"after"})),!1}))):(a("#layout_"+this.name+"_panel_bottom").hide(),a("#layout_"+this.name+"_resizer_bottom").hide()),h=0+(u?p.sizeCalculated+this.padding:0),i=0+(w?r.sizeCalculated+this.padding:0),j=f-(u?p.sizeCalculated+this.padding:0)-(v?q.sizeCalculated+this.padding:0),k=g-(w?r.sizeCalculated+this.padding:0)-(x?s.sizeCalculated+this.padding:0)-(t?o.sizeCalculated+this.padding:0),l=a("#layout_"+this.name+"_panel_main"),window.navigator.userAgent.indexOf("MSIE")!=-1&&l.length>0&&l[0].clientHeight0&&l[0].clientHeightthis.padding?this.resizer:this.padding,a("#layout_"+this.name+"_resizer_preview").show().css({display:"block",left:h+"px",top:i+"px",width:j+"px",height:k+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(b){var c=m.trigger({phase:"before",type:"resizerClick",target:"preview",originalEvent:b});if(c.isCancelled!==!0)return w2ui[m.name].tmp.events.resizeStart("preview",b),m.trigger(a.extend(c,{phase:"after"})),!1}))):(a("#layout_"+this.name+"_panel_preview").hide(),a("#layout_"+this.name+"_resizer_preview").hide());for(var B=0;B .w2ui-panel-",E=0;C&&(C.title&&(E+=w2utils.getSize(a(D+"title").css({top:E+"px",display:"block"}),"height")),C.show.tabs&&(null!=C.tabs&&w2ui[this.name+"_"+c[B]+"_tabs"]&&w2ui[this.name+"_"+c[B]+"_tabs"].resize(),E+=w2utils.getSize(a(D+"tabs").css({top:E+"px",display:"block"}),"height")),C.show.toolbar&&(null!=C.toolbar&&w2ui[this.name+"_"+c[B]+"_toolbar"]&&w2ui[this.name+"_"+c[B]+"_toolbar"].resize(),E+=w2utils.getSize(a(D+"toolbar").css({top:E+"px",display:"block"}),"height"))),a(D+"content").css({display:"block"}).css({top:E+"px"})}return clearTimeout(this._resize_timer),this._resize_timer=setTimeout(function(){for(var b in w2ui)if("function"==typeof w2ui[b].resize){null==w2ui[b].panels&&w2ui[b].resize();var c=a(w2ui[b].box).parents(".w2ui-layout");c.length>0&&c.attr("name")==m.name&&w2ui[b].resize()}},100),this.trigger(a.extend(e,{phase:"after"})),(new Date).getTime()-b}},destroy:function(){var b=this.trigger({phase:"before",type:"destroy",target:this.name});if(b.isCancelled!==!0)return null!=w2ui[this.name]&&(a(this.box).find("#layout_"+this.name+"_panel_main").length>0&&a(this.box).removeAttr("name").removeClass("w2ui-layout").html(""),delete w2ui[this.name],this.trigger(a.extend(b,{phase:"after"})),this.tmp.events&&this.tmp.events.resize&&a(window).off("resize",this.tmp.events.resize),!0)},lock:function(a,b,d){if(c.indexOf(a)==-1)return void console.log("ERROR: First parameter needs to be the a valid panel name.");var e=Array.prototype.slice.call(arguments,0);e[0]="#layout_"+this.name+"_panel_"+a,w2utils.lock.apply(window,e)},unlock:function(a,b){if(c.indexOf(a)==-1)return void console.log("ERROR: First parameter needs to be the a valid panel name.");var d="#layout_"+this.name+"_panel_"+a;w2utils.unlock(d,b)}},a.extend(b.prototype,w2utils.event),w2obj.layout=b}(jQuery);var w2popup={};!function(a){a.fn.w2popup=function(b,c){null==b&&(c={},b="open"),a.isPlainObject(b)&&(c=b,b="open"),b=b.toLowerCase(),"load"===b&&"string"==typeof c&&(c=a.extend({url:c},arguments.length>2?arguments[2]:{})),"open"===b&&null!=c.url&&(b="load"),c=c||{};var d={};if(a(this).length>0&&"open"==b){if(a(this).find("div[rel=title], div[rel=body], div[rel=buttons]").length>0){if(a("#w2ui-popup").length>0){var e=a("#w2ui-popup").data("options");w2popup._prev={template:w2popup._template,title:e.title,body:e.body,buttons:e.buttons}}w2popup._template=this,a(this).find("div[rel=title]").length>0&&(d.title=a(this).find("div[rel=title]")),a(this).find("div[rel=body]").length>0&&(d.body=a(this).find("div[rel=body]"),d.style=a(this).find("div[rel=body]")[0].style.cssText),a(this).find("div[rel=buttons]").length>0&&(d.buttons=a(this).find("div[rel=buttons]"))}else d.title=" ",d.body=a(this).html();0!==parseInt(a(this).css("width"))&&(d.width=parseInt(a(this).css("width"))),0!==parseInt(a(this).css("height"))&&(d.height=parseInt(a(this).css("height")))}return w2popup[b](a.extend({},d,c))},w2popup={defaults:{title:"",body:"",buttons:"",style:"",color:"#000",opacity:.4,speed:.3,modal:!1,maximized:!1,keyboard:!0,width:500,height:300,showClose:!0,showMax:!1,transition:null},status:"closed",handlers:[],onOpen:null,onClose:null,onMax:null,onMin:null,onToggle:null,onKeydown:null,open:function(b){function c(b){return b||(b=window.event),w2popup.status="moving",p.resizing=!0,p.isLocked=1==a("#w2ui-popup > .w2ui-lock").length,p.x=b.screenX,p.y=b.screenY,p.pos_x=a("#w2ui-popup").position().left,p.pos_y=a("#w2ui-popup").position().top,p.isLocked||w2popup.lock({opacity:0}),a(document).on("mousemove",p.mvMove),a(document).on("mouseup",p.mvStop),b.stopPropagation?b.stopPropagation():b.cancelBubble=!0,!!b.preventDefault&&void b.preventDefault()}function d(b){1==p.resizing&&(b||(b=window.event),p.div_x=b.screenX-p.x,p.div_y=b.screenY-p.y,a("#w2ui-popup").css(w2utils.cssPrefix({transition:"none",transform:"translate3d("+p.div_x+"px, "+p.div_y+"px, 0px)"})))}function e(b){1==p.resizing&&(b||(b=window.event),w2popup.status="open",p.div_x=b.screenX-p.x,p.div_y=b.screenY-p.y,a("#w2ui-popup").css({left:p.pos_x+p.div_x+"px",top:p.pos_y+p.div_y+"px"}).css(w2utils.cssPrefix({transition:"none",transform:"translate3d(0px, 0px, 0px)"})),p.resizing=!1,a(document).off("mousemove",p.mvMove),a(document).off("mouseup",p.mvStop),p.isLocked||w2popup.unlock())}var f=this;if("closing"==w2popup.status)return void setTimeout(function(){f.open.call(f,b)},100);var g=a("#w2ui-popup").data("options"),b=a.extend({},this.defaults,g,{title:"",body:"",buttons:""},b,{maximized:!1});setTimeout(function(){a("#w2ui-popup").data("options",b)},100),0===a("#w2ui-popup").length&&(w2popup.onMax=null,w2popup.onMin=null,w2popup.onToggle=null,w2popup.onOpen=null,w2popup.onClose=null,w2popup.onKeydown=null),b.onOpen&&(w2popup.onOpen=b.onOpen),b.onClose&&(w2popup.onClose=b.onClose),b.onMax&&(w2popup.onMax=b.onMax),b.onMin&&(w2popup.onMin=b.onMin),b.onToggle&&(w2popup.onToggle=b.onToggle),b.onKeydown&&(w2popup.onKeydown=b.onKeydown),b.width=parseInt(b.width),b.height=parseInt(b.height);var h,i;void 0==window.innerHeight?(h=parseInt(document.documentElement.offsetWidth),i=parseInt(document.documentElement.offsetHeight),"IE7"===w2utils.engine&&(h+=21,i+=4)):(h=parseInt(window.innerWidth),i=parseInt(window.innerHeight)),h-10';a("body").append(n);var o=a("#w2ui-popup");if(o.find("div[rel=title], div[rel=body], div[rel=buttons]").length>0){var p=o.find("div[rel=title]");p.length>0&&(b.title=p.html(),p.remove());var p=o.find("div[rel=buttons]");p.length>0&&(b.buttons=p.html(),p.remove());var p=o.find("div[rel=body]");p.length>0?b.body=p.html():b.body=o.html()}var n='
    '+m+'
    ';a("#w2ui-popup").html(n),b.title&&a("#w2ui-popup .w2ui-popup-title").append(b.title),b.buttons&&a("#w2ui-popup .w2ui-popup-buttons").append(b.buttons),b.body&&a("#w2ui-popup .w2ui-popup-body").append(b.body),setTimeout(function(){a("#w2ui-popup").css("opacity","1").css(w2utils.cssPrefix({transition:b.speed+"s opacity, "+b.speed+"s -webkit-transform",transform:"scale(1)"})),f.focus()},1),setTimeout(function(){a("#w2ui-popup").css(w2utils.cssPrefix("transform","")),w2popup.status="open",setTimeout(function(){f.trigger(a.extend(l,{phase:"after"}))},100)},1e3*b.speed)}else{null==w2popup._prev&&null!=w2popup._template&&f.restoreTemplate();var l=this.trigger({phase:"before",type:"open",target:"popup",options:b,present:!0});if(l.isCancelled===!0)return;w2popup.status="opening",null!=g&&(g.maximized||g.width==b.width&&g.height==b.height||w2popup.resize(b.width,b.height),b.prevSize=b.width+"px:"+b.height+"px",b.maximized=g.maximized);var q=a("#w2ui-popup .w2ui-box").clone();if(q.removeClass("w2ui-box").addClass("w2ui-box-temp").find(".w2ui-popup-body").empty().append(b.body),"string"==typeof b.body&&q.find("div[rel=title], div[rel=body], div[rel=buttons]").length>0){var p=q.find("div[rel=title]");p.length>0&&(b.title=p.html(),p.remove());var p=q.find("div[rel=buttons]");p.length>0&&(b.buttons=p.html(),p.remove());var p=q.find("div[rel=body]");p.length>0?b.body=p.html():b.body=q.html(),q.html(b.body)}a("#w2ui-popup .w2ui-box").after(q),b.buttons?(a("#w2ui-popup .w2ui-popup-buttons").show().html("").append(b.buttons),a("#w2ui-popup .w2ui-popup-body").removeClass("w2ui-popup-no-buttons"),a("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("bottom","")):(a("#w2ui-popup .w2ui-popup-buttons").hide().html(""),a("#w2ui-popup .w2ui-popup-body").addClass("w2ui-popup-no-buttons"),a("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("bottom","0px")),b.title?(a("#w2ui-popup .w2ui-popup-title").show().html((b.showClose?'
    Close
    ':"")+(b.showMax?'
    Max
    ':"")).append(b.title),a("#w2ui-popup .w2ui-popup-body").removeClass("w2ui-popup-no-title"),a("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("top","")):(a("#w2ui-popup .w2ui-popup-title").hide().html(""),a("#w2ui-popup .w2ui-popup-body").addClass("w2ui-popup-no-title"),a("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("top","0px"));var r=a("#w2ui-popup .w2ui-box")[0],s=a("#w2ui-popup .w2ui-box-temp")[0];w2utils.transition(r,s,b.transition,function(){f.restoreTemplate(),a(r).remove(),a(s).removeClass("w2ui-box-temp").addClass("w2ui-box");var c=a(s).find(".w2ui-popup-body");1==c.length&&(c[0].style.cssText=b.style),a("#w2ui-popup").data("prev-size",null),f.focus(),w2popup.status="open",f.trigger(a.extend(l,{phase:"after"}))})}b._last_focus=a(":focus"),b.keyboard&&a(document).on("keydown",this.keydown);var p={resizing:!1,mvMove:d,mvStop:e};return a("#w2ui-popup .w2ui-popup-title").on("mousedown",function(a){w2popup.get().maximized||c(a)}),this},keydown:function(b){var c=a("#w2ui-popup").data("options");if(!c||c.keyboard){var d=w2popup.trigger({phase:"before",type:"keydown",target:"popup",options:c,originalEvent:b});if(d.isCancelled!==!0){switch(b.keyCode){case 27:b.preventDefault(),a("#w2ui-popup .w2ui-message").length>0?w2popup.message():w2popup.close()}w2popup.trigger(a.extend(d,{phase:"after"}))}}},close:function(b){var c=this,b=a.extend({},a("#w2ui-popup").data("options"),b);if(0!==a("#w2ui-popup").length&&"closed"!=this.status){if("opening"==this.status)return void setTimeout(function(){w2popup.close()},100);var d=this.trigger({phase:"before",type:"close",target:"popup",options:b});d.isCancelled!==!0&&(w2popup.status="closing",a("#w2ui-popup").css("opacity","0").css(w2utils.cssPrefix({transition:b.speed+"s opacity, "+b.speed+"s -webkit-transform",transform:"scale(0.9)"})),w2popup.unlockScreen(b),setTimeout(function(){c.restoreTemplate(),a("#w2ui-popup").remove(),w2popup.status="closed",b._last_focus.length>0&&b._last_focus.focus(),c.trigger(a.extend(d,{phase:"after"}))},1e3*b.speed),b.keyboard&&a(document).off("keydown",this.keydown))}},toggle:function(){var b=this,c=a("#w2ui-popup").data("options"),d=this.trigger({phase:"before",type:"toggle",target:"popup",options:c});d.isCancelled!==!0&&(c.maximized===!0?w2popup.min():w2popup.max(),setTimeout(function(){b.trigger(a.extend(d,{phase:"after"}))},1e3*c.speed+50))},max:function(){var b=this,c=a("#w2ui-popup").data("options");if(c.maximized!==!0){var d=this.trigger({phase:"before",type:"max",target:"popup",options:c});d.isCancelled!==!0&&(w2popup.status="resizing",c.prevSize=a("#w2ui-popup").css("width")+":"+a("#w2ui-popup").css("height"),w2popup.resize(1e4,1e4,function(){w2popup.status="open",c.maximized=!0,b.trigger(a.extend(d,{phase:"after"})),a("#w2ui-popup .w2ui-grid, #w2ui-popup .w2ui-form, #w2ui-popup .w2ui-layout").each(function(){var b=a(this).attr("name");w2ui[b]&&w2ui[b].resize&&w2ui[b].resize()})}))}},min:function(){var b=this,c=a("#w2ui-popup").data("options");if(c.maximized===!0){var d=c.prevSize.split(":"),e=this.trigger({phase:"before",type:"min",target:"popup",options:c});e.isCancelled!==!0&&(w2popup.status="resizing",w2popup.resize(parseInt(d[0]),parseInt(d[1]),function(){w2popup.status="open",c.maximized=!1,c.prevSize=null,b.trigger(a.extend(e,{phase:"after"})),a("#w2ui-popup .w2ui-grid, #w2ui-popup .w2ui-form, #w2ui-popup .w2ui-layout").each(function(){var b=a(this).attr("name");w2ui[b]&&w2ui[b].resize&&w2ui[b].resize()})}))}},get:function(){return a("#w2ui-popup").data("options")},set:function(a){w2popup.open(a)},clear:function(){a("#w2ui-popup .w2ui-popup-title").html(""),a("#w2ui-popup .w2ui-popup-body").html(""),a("#w2ui-popup .w2ui-popup-buttons").html("")},reset:function(){w2popup.open(w2popup.defaults)},load:function(b){function c(c,d){if(delete b.url,a("body").append('"),null!=d&&a("#w2ui-tmp #"+d).length>0?a("#w2ui-tmp #"+d).w2popup(b):a("#w2ui-tmp > div").w2popup(b),a("#w2ui-tmp > style").length>0){var e=a("
    ").append(a("#w2ui-tmp > style").clone()).html();0===a("#w2ui-popup #div-style").length&&a("#w2ui-popup").append('
    '), +a("#w2ui-popup #div-style").html(e)}a("#w2ui-tmp").remove()}if(w2popup.status="loading",null==b.url)return void console.log("ERROR: The url parameter is empty.");var d=String(b.url).split("#"),e=d[0],f=d[1];null==b&&(b={});var g=a("#w2ui-popup").data(e);null!=g?c(g,f):a.get(e,function(b,d,g){c(g.responseText,f),a("#w2ui-popup").data(e,g.responseText)})},message:function(b){var c=this;a().w2tag(),b||(b={width:200,height:100});var d=parseInt(a("#w2ui-popup").width()),e=parseInt(a("#w2ui-popup").height());b.originalWidth=b.width,b.originalHeight=b.height,parseInt(b.width)<10&&(b.width=10),parseInt(b.height)<10&&(b.height=10),null==b.hideOnClick&&(b.hideOnClick=!1);var f=a("#w2ui-popup").data("options")||{},g=parseInt(a("#w2ui-popup > .w2ui-popup-title").css("height"));(null==b.width||b.width>f.width-10)&&(b.width=f.width-10),(null==b.height||b.height>f.height-g-5)&&(b.height=f.height-g-5),b.originalHeight<0&&(b.height=e+b.originalHeight-g),b.originalWidth<0&&(b.width=d+2*b.originalWidth);var h=a("#w2ui-popup .w2ui-popup-title"),i=a("#w2ui-popup .w2ui-message").length;if(""===a.trim(b.html)&&""===a.trim(b.body)&&""===a.trim(b.buttons)){var j=a("#w2ui-popup #w2ui-message"+(i-1)),b=j.data("options")||{};j.css(w2utils.cssPrefix({transition:"0.15s",transform:"translateY(-"+b.height+"px)"})),1==i?w2popup.unlock(150):a("#w2ui-popup #w2ui-message"+(i-2)).css("z-index",1500),setTimeout(function(){var a=j.data("prev_focus");j.remove(),a&&a.length>0?a.focus():c.focus(),"function"==typeof b.onClose&&b.onClose()},150)}else{""===a.trim(b.body)&&""===a.trim(b.buttons)||(b.html='
    '+b.body+'
    '+b.buttons+"
    "),a("#w2ui-popup .w2ui-message").css("z-index",1390),h.css("z-index",1501),a("#w2ui-popup .w2ui-box").before('"),a("#w2ui-popup #w2ui-message"+i).data("options",b).data("prev_focus",a(":focus"));var k=a("#w2ui-popup #w2ui-message"+i).css("display");a("#w2ui-popup #w2ui-message"+i).css(w2utils.cssPrefix({transform:"none"==k?"translateY(-"+b.height+"px)":"translateY(0px)"})),"none"==k&&(a("#w2ui-popup #w2ui-message"+i).show().html(b.html),setTimeout(function(){a("#w2ui-popup #w2ui-message"+i).css(w2utils.cssPrefix({transform:"none"==k?"translateY(0px)":"translateY(-"+b.height+"px)"}))},1),0===i&&w2popup.lock(),setTimeout(function(){c.focus(),a("#w2ui-popup #w2ui-message"+i).css(w2utils.cssPrefix({transition:"0s"})),"function"==typeof b.onOpen&&b.onOpen()},350))}},focus:function(){var b=null,c=a("#w2ui-popup"),d="input:visible, button:visible, select:visible, textarea:visible";a(c).find(d).off(".keep-focus");var e=a("#w2ui-popup .w2ui-message").length-1,f=a("#w2ui-popup #w2ui-message"+e);if(f.length>0){var g=a(f[f.length-1]).find("button");g.length>0&&g[0].focus(),b=f}else if(c.length>0){var g=c.find(".w2ui-popup-buttons button");g.length>0&&g[0].focus(),b=c}a(b).find(d).on("blur.keep-focus",function(c){setTimeout(function(){var c=a(":focus");if(c.length>0&&!a(b).find(d).is(c)||c.hasClass("w2ui-popup-hidden")){var e=a(b).find(d);e.length>0&&e[0].focus()}},1)})},lock:function(b,c){var d=Array.prototype.slice.call(arguments,0);d.unshift(a("#w2ui-popup")),w2utils.lock.apply(window,d)},unlock:function(b){w2utils.unlock(a("#w2ui-popup"),b)},lockScreen:function(b){return!(a("#w2ui-lock").length>0)&&(null==b&&(b=a("#w2ui-popup").data("options")),null==b&&(b={}),b=a.extend({},w2popup.defaults,b),a("body").append('
    '),setTimeout(function(){a("#w2ui-lock").css("opacity",b.opacity).css(w2utils.cssPrefix("transition",b.speed+"s opacity"))},1),1==b.modal?(a("#w2ui-lock").on("mousedown",function(){a("#w2ui-lock").css("opacity","0.6").css(w2utils.cssPrefix("transition",".1s"))}),a("#w2ui-lock").on("mouseup",function(){setTimeout(function(){a("#w2ui-lock").css("opacity",b.opacity).css(w2utils.cssPrefix("transition",".1s"))},100)})):a("#w2ui-lock").on("mousedown",function(){w2popup.close()}),!0)},unlockScreen:function(b){return 0!==a("#w2ui-lock").length&&(null==b&&(b=a("#w2ui-popup").data("options")),null==b&&(b={}),b=a.extend({},w2popup.defaults,b),a("#w2ui-lock").css("opacity","0").css(w2utils.cssPrefix("transition",b.speed+"s opacity")),setTimeout(function(){a("#w2ui-lock").remove()},1e3*b.speed),!0)},resizeMessages:function(){a("#w2ui-popup").data("options");a("#w2ui-popup .w2ui-message").each(function(){var b=a(this).data("options"),c=a("#w2ui-popup");parseInt(b.width)<10&&(b.width=10),parseInt(b.height)<10&&(b.height=10);var d=parseInt(c.find("> .w2ui-popup-title").css("height")),e=parseInt(c.width()),f=parseInt(c.height());b.width=b.originalWidth,b.width>e-10&&(b.width=e-10),b.height=b.originalHeight,b.height>f-d-5&&(b.height=f-d-5),b.originalHeight<0&&(b.height=f+b.originalHeight-d),b.originalWidth<0&&(b.width=e+2*b.originalWidth),a(this).css({left:(e-b.width)/2+"px",width:b.width+"px",height:b.height+"px"})})},resize:function(b,c,d){var e=this,f=a("#w2ui-popup").data("options");b=parseInt(b),c=parseInt(c);var g,h;void 0==window.innerHeight?(g=parseInt(document.documentElement.offsetWidth),h=parseInt(document.documentElement.offsetHeight),"IE7"===w2utils.engine&&(g+=21,h+=4)):(g=parseInt(window.innerWidth),h=parseInt(window.innerHeight)),g-100&&"closing"!=w2popup.status?w2popup.message({width:400,height:170,body:'
    '+a+"
    ",buttons:'",onOpen:function(){d("#w2ui-popup .w2ui-message .w2ui-popup-btn").focus()},onClose:function(){"function"==typeof c&&c()}}):w2popup.open({width:450,height:220,showMax:!1,showClose:!1,title:b,body:'
    '+a+"
    ",buttons:'",onOpen:function(a){setTimeout(function(){d("#w2ui-popup .w2ui-popup-btn").focus()},1)},onKeydown:function(a){d("#w2ui-popup .w2ui-popup-btn").focus().addClass("clicked")},onClose:function(){"function"==typeof c&&c()}}),{ok:function(a){return c=a,this},done:function(a){return c=a,this}}},w2confirm=function(a,b,c){var d=jQuery,e={},f={msg:"",title:w2utils.lang("Confirmation"),width:d("#w2ui-popup").length>0?400:450,height:d("#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,callBack:null};return 1==arguments.length&&"object"==typeof a?d.extend(e,f,a):"function"==typeof b?d.extend(e,f,{msg:a,callBack:b}):d.extend(e,f,{msg:a,title:b,callBack:c}),"object"==typeof e.btn_yes&&(e.yes_text=e.btn_yes.text||e.yes_text,e.yes_class=e.btn_yes.class||e.yes_class,e.yes_style=e.btn_yes.style||e.yes_style,e.yes_callBack=e.btn_yes.callBack||e.yes_callBack),"object"==typeof e.btn_no&&(e.no_text=e.btn_no.text||e.no_text,e.no_class=e.btn_no.class||e.no_class,e.no_style=e.btn_no.style||e.no_style,e.no_callBack=e.btn_no.callBack||e.no_callBack),d("#w2ui-popup").length>0&&"closing"!=w2popup.status&&w2popup.get()?(e.width>w2popup.get().width&&(e.width=w2popup.get().width),e.height>w2popup.get().height-50&&(e.height=w2popup.get().height-50),w2popup.message({width:e.width,height:e.height,body:'
    '+e.msg+"
    ",buttons:'",onOpen:function(){d("#w2ui-popup .w2ui-message .w2ui-btn").on("click.w2confirm",function(a){w2popup._confirm_btn=a.target.id,w2popup.message()})},onClose:function(){d("#w2ui-popup .w2ui-message .w2ui-btn").off("click.w2confirm"),setTimeout(function(){"function"==typeof e.callBack&&e.callBack(w2popup._confirm_btn),"Yes"==w2popup._confirm_btn&&"function"==typeof e.yes_callBack&&e.yes_callBack(),"No"==w2popup._confirm_btn&&"function"==typeof e.no_callBack&&e.no_callBack()},300)}})):(w2utils.isInt(e.height)||(e.height=e.height+50),w2popup.open({width:e.width,height:e.height,title:e.title,modal:!0,showClose:!1,body:'
    '+e.msg+"
    ",buttons:'",onOpen:function(a){setTimeout(function(){d("#w2ui-popup .w2ui-popup-btn").on("click",function(a){w2popup.close(),"function"==typeof e.callBack&&e.callBack(a.target.id),"Yes"==a.target.id&&"function"==typeof e.yes_callBack&&e.yes_callBack(),"No"==a.target.id&&"function"==typeof e.no_callBack&&e.no_callBack()}),d("#w2ui-popup .w2ui-popup-btn#Yes").focus()},1)},onKeydown:function(a){if(0===d("#w2ui-popup .w2ui-message").length)switch(a.originalEvent.keyCode){case 13:d("#w2ui-popup .w2ui-popup-btn#Yes").focus().addClass("clicked"),w2popup.close();break;case 27:d("#w2ui-popup .w2ui-popup-btn#No").focus().click(),w2popup.close()}}})),{yes:function(a){return e.yes_callBack=a,this},no:function(a){return e.no_callBack=a,this}}},w2prompt=function(a,b,c){var d=jQuery,e={},f={label:"",value:"",attrs:"",title:w2utils.lang("Notification"),ok_text:w2utils.lang("Ok"),cancel_text:w2utils.lang("Cancel"),width:d("#w2ui-popup").length>0?400:450,height:d("#w2ui-popup").length>0?170:220,callBack:null};return 1==arguments.length&&"object"==typeof a?d.extend(e,f,a):"function"==typeof b?d.extend(e,f,{label:a,callBack:b}):d.extend(e,f,{label:a,title:b,callBack:c}),d("#w2ui-popup").length>0&&"closing"!=w2popup.status&&w2popup.get()?(e.width>w2popup.get().width&&(e.width=w2popup.get().width),e.height>w2popup.get().height-50&&(e.height=w2popup.get().height-50),w2popup.message({width:e.width,height:e.height,body:'
    ",buttons:'",onOpen:function(){d("#w2prompt").val(e.value),d("#w2ui-popup .w2ui-message .w2ui-btn#Ok").on("click.w2prompt",function(a){w2popup._prompt_value=d("#w2prompt").val(),w2popup.message()}),d("#w2ui-popup .w2ui-message .w2ui-btn#Cancel").on("click.w2prompt",function(a){w2popup._prompt_value=null,w2popup.message()}),setTimeout(function(){d("#w2prompt").focus()},100)},onClose:function(){d("#w2ui-popup .w2ui-message .w2ui-btn").off("click.w2prompt"),setTimeout(function(){"function"==typeof e.callBack&&null!=w2popup._prompt_value&&e.callBack(w2popup._prompt_value)},300)}})):(w2utils.isInt(e.height)||(e.height=e.height+50),w2popup.open({width:e.width,height:e.height,title:e.title,modal:!0,showClose:!1,body:'
    ',buttons:'",onOpen:function(a){setTimeout(function(){d("#w2prompt").val(e.value),d("#w2prompt").w2field("text"),d("#w2ui-popup .w2ui-popup-btn#Ok").on("click",function(a){w2popup._prompt_value=d("#w2prompt").val(),w2popup.close(),"function"==typeof e.callBack&&e.callBack(w2popup._prompt_value)}),d("#w2ui-popup .w2ui-popup-btn#Cancel").on("click",function(a){w2popup._prompt_value=null,w2popup.close()}),d("#w2ui-popup .w2ui-popup-btn#Ok"),setTimeout(function(){d("#w2prompt").focus()},100)},1)},onKeydown:function(a){if(0===d("#w2ui-popup .w2ui-message").length)switch(a.originalEvent.keyCode){case 13:d("#w2ui-popup .w2ui-popup-btn#Ok").focus().addClass("clicked"),w2popup.close();break;case 27:w2popup.close()}}})),{change:function(a){return d("#w2prompt").on("keyup",a).keyup(),this},ok:function(a){return e.callBack=a,this}}};!function(a){var b=function(b){this.box=null,this.name=null,this.active=null,this.flow="down",this.tooltip="top|left",this.tabs=[],this.routeData={},this.right="",this.style="",a.extend(this,{handlers:[]}),a.extend(!0,this,w2obj.tabs,b)};a.fn.w2tabs=function(c){if(a.isPlainObject(c)){if(!w2utils.checkName(c,"w2tabs"))return;for(var d=c.tabs||[],e=new b(c),f=0;f0?(g[c]&&g[c].apply(g,Array.prototype.slice.call(arguments,1)),this):g:null},b.prototype={onClick:null,onClose:null,onRender:null,onRefresh:null,onResize:null,onDestroy:null,tab:{id:null,text:null,route:null,hidden:!1,disabled:!1,closable:!1,tooltip:null,style:"",onClick:null,onRefresh:null,onClose:null},add:function(a){return this.insert(null,a)},insert:function(c,d){a.isArray(d)||(d=[d]);for(var e=0;e
    ");var j=i+'
    "+w2utils.lang(g)+"
    ";if(0===h.length){var k="";f.hidden&&(k+="display: none;"),f.disabled&&(k+="opacity: 0.2;");var l=''+j+"";this.get(b,!0)!==this.tabs.length-1&&a(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(b,!0))+1].id)).length>0?a(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(b,!0))+1].id)).before(l):a(this.box).find("#tabs_"+this.name+"_right").before(l)}else h.html(j),f.hidden?h.css("display","none"):h.css("display",""),f.disabled?h.css({opacity:"0.2"}):h.css({opacity:"1"})}return a("#tabs_"+this.name+"_right").html(this.right),this.trigger(a.extend(d,{phase:"after"})),(new Date).getTime()-c}},render:function(b){var c=(new Date).getTime(),d=this.trigger({phase:"before",type:"render",target:this.name,box:b});if(d.isCancelled!==!0){if(null!=b&&(a(this.box).find("> table #tabs_"+this.name+"_right").length>0&&a(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-tabs").html(""),this.box=b),!this.box)return!1;var e='
    '+this.right+'
    ";return a(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-tabs").html(e),a(this.box).length>0&&(a(this.box)[0].style.cssText+=this.style),this.trigger(a.extend(d,{phase:"after"})),this.refresh(),this.resize(),(new Date).getTime()-c}},scroll:function(b){var c,d,e,f=a(this.box),g=this,h=f.find(".w2ui-scroll-wrapper"),i=h.scrollLeft();switch(b){case"left":c=h.outerWidth(),d=h.find(":first").outerWidth(),e=i-c+50,e<=0&&(e=0),h.animate({scrollLeft:e},300);break;case"right":c=h.outerWidth(),d=h.find(":first").outerWidth(),e=i+c-50,e>=d-c&&(e=d-c),h.animate({scrollLeft:e},300)}setTimeout(function(){g.resize()},350)},resize:function(){var b=(new Date).getTime(),c=this.trigger({phase:"before",type:"resize",target:this.name});if(c.isCancelled!==!0){var d=a(this.box);d.find(".w2ui-scroll-left, .w2ui-scroll-right").hide();var e=d.find(".w2ui-scroll-wrapper");return e.find(":first").outerWidth()>e.outerWidth()&&(e.scrollLeft()>0&&d.find(".w2ui-scroll-left").show(),e.scrollLeft() table #tabs_"+this.name+"_right").length>0&&a(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-tabs").html(""),delete w2ui[this.name],this.trigger(a.extend(b,{phase:"after"})))},click:function(b,c){var d=this.get(b);if(null==d||d.disabled)return!1;var e=this.trigger({phase:"before",type:"click",target:b,tab:d,object:d,originalEvent:c});if(e.isCancelled!==!0){if(a(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.active)+" .w2ui-tab").removeClass("active"),this.active=d.id,"string"==typeof d.route){var f=""!==d.route?String("/"+d.route).replace(/\/{2,}/g,"/"):"",g=w2utils.parseRoute(f);if(g.keys.length>0)for(var h=0;h'),setTimeout(function(){a(f.box).find("#tabs_"+f.name+"_tab_"+w2utils.escapeId(d.id)).find(":first-child").css({width:"0px"})},50)},200),setTimeout(function(){f.remove(b)},450),this.trigger(a.extend(e,{phase:"after"})),this.refresh()}},animateInsert:function(b,c){if(null!=this.get(b)&&a.isPlainObject(c)&&w2utils.checkUniqueId(c.id,this.tabs,"tabs",this.name)){var d=a(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(c.id));if(0===d.length){null==c.text&&null!=c.caption&&(c.text=c.caption);var e='
    '+(c.closable?'
    ':"")+'
    '+c.text+"
    ";a("body").append(e);var f='
     
    ',g="";c.hidden&&(g+="display: none;"),c.disabled&&(g+="opacity: 0.2;");var h=''+f+"";this.get(b,!0)!==this.tabs.length&&a(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(b,!0))].id)).length>0?a(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(b,!0))].id)).before(h):a(this.box).find("#tabs_"+this.name+"_right").before(h);var i=this;setTimeout(function(){var b=a("#_tmp_simple_tab").width();a("#_tmp_tabs").remove(),a("#tabs_"+i.name+"_tab_"+w2utils.escapeId(c.id)+" > div").css("width",b+"px")},1),setTimeout(function(){i.insert(b,c)},200)}}}},a.extend(b.prototype,w2utils.event),w2obj.tabs=b}(jQuery),function(a){var b=function(b){this.box=null,this.name=null,this.routeData={},this.items=[],this.right="",this.tooltip="top|left",a.extend(!0,this,w2obj.toolbar,b)};a.fn.w2toolbar=function(c){if(a.isPlainObject(c)){if(!w2utils.checkName(c,"w2toolbar"))return;var d=c.items||[],e=new b(c);a.extend(e,{items:[],handlers:[]});for(var f=0;f0?(j[c]&&j[c].apply(j,Array.prototype.slice.call(arguments,1)),this):j:null},b.prototype={onClick:null,onRender:null,onRefresh:null,onResize:null,onDestroy:null,item:{id:null,type:"button",text:null,html:"",tooltip:null,count:null,hidden:!1,disabled:!1,checked:!1,img:null,icon:null,route:null,arrow:!0,style:null,color:null,transparent:null,group:null,items:null,selected:null,overlay:{},onClick:null,onRefresh:null},add:function(a){this.insert(null,a)},insert:function(c,d){a.isArray(d)||(d=[d]);for(var e=0;e1){var g=this.get(b);return void(g&&!g.disabled&&d.menuClick({name:d.name,item:f,subItem:g,originalEvent:c}))}if(f&&!f.disabled){var h=this.trigger({phase:"before",type:"click",target:null!=b?b:this.name,item:f,object:f,originalEvent:c});if(h.isCancelled===!0)return;var i="#tb_"+this.name+"_item_"+w2utils.escapeId(f.id)+" table.w2ui-button";if(a(i).removeClass("down"),"radio"==f.type){for(var j=0;j19&&(g=19),"drop"==f.type&&e.w2overlay(f.html,a.extend({name:d.name,left:g,top:3},f.overlay,{onHide:function(a){b()}})),["menu","menu-radio","menu-check"].indexOf(f.type)!=-1){var h="normal";"menu-radio"==f.type&&(h="radio",f.items.forEach(function(a){f.selected==a.id?a.checked=!0:a.checked=!1})),"menu-check"==f.type&&(h="check",f.items.forEach(function(b){a.isArray(f.selected)&&f.selected.indexOf(b.id)!=-1?b.checked=!0:b.checked=!1})),e.w2menu(a.extend({name:d.name,items:f.items,left:g,top:3},f.overlay,{type:h,select:function(a){d.menuClick({name:d.name,item:f,subItem:a.item,originalEvent:a.originalEvent,keepOpen:a.keepOpen})},onHide:function(a){b()}}))}["color","text-color"].indexOf(f.type)!=-1&&(null==f.transparent&&(f.transparent=!0), +a(e).w2color({color:f.color,transparent:f.transparent},function(a,e){null!=a&&d.colorClick({name:d.name,item:f,color:a,originalEvent:c.originalEvent}),b()}))},1)),["check","menu","menu-radio","menu-check","drop","color","text-color"].indexOf(f.type)!=-1&&(f.checked=!f.checked,f.checked?a(i).addClass("checked"):a(i).removeClass("checked")),f.route){var l=String("/"+f.route).replace(/\/{2,}/g,"/"),m=w2utils.parseRoute(l);if(m.keys.length>0)for(var n=0;n=d-c&&(e=d-c),h.animate({scrollLeft:e},300)}setTimeout(function(){g.resize()},350)},render:function(b){var c=(new Date).getTime(),d=this.trigger({phase:"before",type:"render",target:this.name,box:b});if(d.isCancelled!==!0&&(null!=b&&(a(this.box).find("> table #tb_"+this.name+"_right").length>0&&a(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-toolbar").html(""),this.box=b),this.box)){for(var e='
    ',f=0;f':'')}return e+='",e+='
    '+this.right+"
    ",a(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-toolbar").html(e),a(this.box).length>0&&(a(this.box)[0].style.cssText+=this.style),this.refresh(),this.resize(),this.trigger(a.extend(d,{phase:"after"})),(new Date).getTime()-c}},refresh:function(b){var c=(new Date).getTime(),d=this.trigger({phase:"before",type:"refresh",target:null!=b?b:this.name,item:this.get(b)});if(d.isCancelled!==!0){if(null!=b){var e=this.get(b);if(null==e)return!1;if("function"==typeof e.onRefresh){var f=this.trigger({phase:"before",type:"refresh",target:b,item:e,object:e});if(f.isCancelled===!0)return}var g=a(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(e.id)),h=this.getItemHTML(e);return 0===g.length?(h="spacer"==e.type?'':''+h+"",this.get(b,!0)==this.items.length-1?a(this.box).find("#tb_"+this.name+"_right").before(h):a(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(this.items[parseInt(this.get(b,!0))+1].id)).before(h)):(["menu","menu-radio","menu-check","drop","color","text-color"].indexOf(e.type)!=-1&&0==e.checked&&a("#w2ui-overlay-"+this.name).length>0&&a("#w2ui-overlay-"+this.name)[0].hide(),g.html(h),e.hidden?g.css("display","none"):g.css("display",""),e.disabled?g.addClass("disabled"):g.removeClass("disabled")),"function"==typeof e.onRefresh&&this.trigger(a.extend(f,{phase:"after"})),this.trigger(a.extend(d,{phase:"after"})),(new Date).getTime()-c}for(var i=0;ie.outerWidth()&&(e.scrollLeft()>0&&d.find(".w2ui-scroll-left").show(),e.scrollLeft() table #tb_"+this.name+"_right").length>0&&a(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-toolbar").html(""),a(this.box).html(""),delete w2ui[this.name],this.trigger(a.extend(b,{phase:"after"})))},getItemHTML:function(a){var b="";null!=a.caption&&null==a.text&&(a.text=a.caption),null==a.text&&(a.text=""),null==a.tooltip&&null!=a.hint&&(a.tooltip=a.hint),null==a.tooltip&&(a.tooltip="");var c=" ",d=a.text;if("function"==typeof d&&(d=d.call(this,a)),a.img&&(c='
    '),a.icon&&(c='
    '),""===b)switch(a.type){case"color":case"text-color":"string"==typeof a.color&&"#"==a.color.substr(0,1)&&(a.color=a.color.substr(1)),"color"==a.type&&(d='
    '+(a.text?'
    '+w2utils.lang(a.text)+"
    ":"")),"text-color"==a.type&&(d='
    '+(a.text?w2utils.lang(a.text):"Aa")+"
    ");case"menu":case"menu-check":case"menu-radio":case"button":case"check":case"radio":case"drop":b+='
    '+c+(""!==d?'":"")+(null!=a.count?'":"")+(["menu","menu-radio","menu-check","drop","color","text-color"].indexOf(a.type)!=-1&&a.arrow!==!1?'':"")+"
    '+w2utils.lang(d)+"'+a.count+"
    ";break;case"break":b+='
     
    ';break;case"html":b+='
    '+("function"==typeof a.html?a.html.call(this,a):a.html)+"
    "}return"
    "+b+"
    "},tooltipShow:function(b,c,d){if(null!=this.tooltip){var e=a(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(b)),f=this.get(b),g=this.tooltip,h=f.tooltip;"function"==typeof h&&(h=h.call(this,f)),e.prop("_mouse_over",!0),setTimeout(function(){if(e.prop("_mouse_over")===!0&&e.prop("_mouse_tooltip")!==!0){if(e.prop("_mouse_tooltip",!0),["menu","menu-radio","menu-check","drop","color","text-color"].indexOf(f.type)!=-1&&1==f.checked)return;e.w2tag(w2utils.lang(h),{position:g})}1==d&&e.w2tag(w2utils.lang(h),{position:g})},1)}},tooltipHide:function(b,c){if(null!=this.tooltip){var d=a(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(b));this.get(b);d.removeProp("_mouse_over"),setTimeout(function(){d.prop("_mouse_over")!==!0&&d.prop("_mouse_tooltip")===!0&&(d.removeProp("_mouse_tooltip"),d.w2tag())},1)}},menuClick:function(b){var c=this;if(b.item&&!b.item.disabled){var d=this.trigger({phase:"before",type:"click",target:b.item.id+":"+b.subItem.id,item:b.item,subItem:b.subItem,originalEvent:b.originalEvent});if(d.isCancelled===!0)return;var e=b.subItem,f=this.get(b.item.id);if("menu-radio"==f.type&&(f.selected=e.id,b.item.items.forEach(function(a){a.checked=!1}),e.checked=!0),"menu-check"==f.type){a.isArray(f.selected)||(f.selected=[]);var g=f.selected.indexOf(e.id);g==-1?(f.selected.push(e.id),e.checked=!0):(f.selected.splice(g,1),e.checked=!1)}if("string"==typeof e.route){var h=""!==e.route?String("/"+e.route).replace(/\/{2,}/g,"/"):"",i=w2utils.parseRoute(h);if(i.keys.length>0)for(var j=0;j0?(f[c]&&f[c].apply(f,Array.prototype.slice.call(arguments,1)),this):f:null},b.prototype={onClick:null,onDblClick:null,onContextMenu:null,onMenuClick:null,onExpand:null,onCollapse:null,onKeydown:null,onRender:null,onRefresh:null,onResize:null,onDestroy:null,onFocus:null,onBlur:null,onFlat:null,node:{id:null,text:"",count:null,img:null,icon:null,nodes:[],style:"",route:null,selected:!1,expanded:!1,hidden:!1,disabled:!1,group:!1,groupShowHide:!0,collapsible:!0,plus:!1,onClick:null,onDblClick:null,onContextMenu:null,onExpand:null,onCollapse:null,parent:null,sidebar:null},add:function(a,b){return 1==arguments.length&&(b=arguments[0],a=this),"string"==typeof a&&(a=this.get(a)),this.insert(a,null,b)},insert:function(c,d,e){var f,g,h,i,j;if(2==arguments.length)if(e=arguments[1],d=arguments[0],null!=d){if(g=this.get(d),null==g)return a.isArray(e)||(e=[e]),f=null!=e[0].caption?e[0].caption:e[0].text,console.log('ERROR: Cannot insert node "'+f+'" because cannot find node "'+d+'" to insert before.'),null;c=this.get(d).parent}else c=this;"string"==typeof c&&(c=this.get(c)),a.isArray(e)||(e=[e]);for(var k=0;k0&&this.insert(h,null,j)}else f=null!=i.caption?i.caption:i.text,console.log("ERROR: Cannot insert node with id="+i.id+" (text: "+f+") because another node with the same id already exists.");else f=null!=i.caption?i.caption:i.text,console.log('ERROR: Cannot insert node "'+f+'" because it has no id.');return this.refresh(c.id),h},remove:function(){for(var a,b=0,c=0;c0&&1==arguments.length?this.refresh(a.parent.id):this.refresh(),b},set:function(b,c,d){if(2==arguments.length&&(d=c,c=b,b=this),"string"==typeof b&&(b=this.get(b)),null==b.nodes)return null;for(var e=0;e0&&(c=this.find(a.nodes[d],b,c))}return c},hide:function(){for(var a=0,b=0;b+'),d.expanded=!1,this.trigger(a.extend(e,{phase:"after"})),setTimeout(function(){c.refresh(b)},200),!0},collapseAll:function(a){if(null==a&&(a=this),"string"==typeof a&&(a=this.get(a)),null==a.nodes)return!1;for(var b=0;b0&&this.collapseAll(a.nodes[b]);return this.refresh(a.id),!0},expand:function(b){var c=this,d=this.get(b),e=this.trigger({phase:"before",type:"expand",target:b,object:d});if(e.isCancelled!==!0)return a(this.box).find("#node_"+w2utils.escapeId(b)+"_sub").slideDown(200),a(this.box).find("#node_"+w2utils.escapeId(b)+" .w2ui-node-dots:first-child").html('
    -
    '),d.expanded=!0,this.trigger(a.extend(e,{phase:"after"})),setTimeout(function(){c.refresh(b)},200),!0},expandAll:function(a){if(null==a&&(a=this),"string"==typeof a&&(a=this.get(a)),null==a.nodes)return!1;for(var b=0;b0&&this.expandAll(a.nodes[b]);this.refresh(a.id)},expandParents:function(a){var b=this.get(a);return null!=b&&(b.parent&&(b.parent.expanded||(b.parent.expanded=!0,this.refresh(b.parent.id)),this.expandParents(b.parent.id)),!0)},click:function(b,c){var d=this,e=this.get(b);if(null!=e&&!e.disabled&&!e.group){a(d.box).find(".w2ui-node.w2ui-selected").each(function(b,c){var e=a(c).attr("id").replace("node_",""),f=d.get(e);null!=f&&(f.selected=!1),a(c).removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected")});var f=a(d.box).find("#node_"+w2utils.escapeId(b)),g=a(d.box).find("#node_"+w2utils.escapeId(d.selected));f.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected"),setTimeout(function(){var h=d.trigger({phase:"before",type:"click",target:b,originalEvent:c,node:e,object:e});if(h.isCancelled===!0)return f.removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected"),void g.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected");if(null!=g&&(g.selected=!1),d.get(b).selected=!0,d.selected=b,"string"==typeof e.route){var i=""!==e.route?String("/"+e.route).replace(/\/{2,}/g,"/"):"",j=w2utils.parseRoute(i);if(j.keys.length>0)for(var k=0;k0&&b!==!0){var g=a.nodes[0];f=g.hidden||g.disabled||g.group?e(g):g}else f=c&&d+10?g(b.nodes[c-1]):b;return null!=d&&(d.hidden||d.disabled||d.group)&&(d=f(d)),d}function g(a){if(a.expanded&&a.nodes.length>0){var b=a.nodes[a.nodes.length-1];return b.hidden||b.disabled||b.group?f(b):g(b)}return a}var h=this,i=h.get(h.selected);if(h.keyboard===!0){i||(i=h.nodes[0]);var j=h.trigger({phase:"before",type:"keydown",target:h.name,originalEvent:b});j.isCancelled!==!0&&(13!=b.keyCode&&32!=b.keyCode||i.nodes.length>0&&h.toggle(h.selected),37==b.keyCode&&(i.nodes.length>0&&i.expanded?h.collapse(h.selected):(c(i.parent),i.parent.group||h.collapse(i.parent.id))),39==b.keyCode&&(i.nodes.length>0||i.plus)&&!i.expanded&&h.expand(h.selected),38==b.keyCode&&c(d(i,f)),40==b.keyCode&&c(d(i,e)),a.inArray(b.keyCode,[13,32,37,38,39,40])!=-1&&(b.preventDefault&&b.preventDefault(),b.stopPropagation&&b.stopPropagation()),h.trigger(a.extend(j,{phase:"after"})))}},scrollIntoView:function(b){null==b&&(b=this.selected);var c=this.get(b);if(null!=c){var d=a(this.box).find(".w2ui-sidebar-div"),e=a(this.box).find("#node_"+w2utils.escapeId(b)),f=e.offset().top-d.offset().top;(f+e.height()>d.height()||f<=0)&&d.animate({scrollTop:d.scrollTop()+f-d.height()/2+e.height()},250,"linear")}},dblClick:function(b,c){var d=this.get(b),e=this.trigger({phase:"before",type:"dblClick",target:b,originalEvent:c,object:d});e.isCancelled!==!0&&(this.toggle(b),this.trigger(a.extend(e,{phase:"after"})))},contextMenu:function(b,c){var d=this,e=d.get(b);b!=d.selected&&d.click(b);var f=d.trigger({phase:"before",type:"contextMenu",target:b,originalEvent:c,object:e,allowOnDisabled:!1});f.isCancelled!==!0&&(e.disabled&&!f.allowOnDisabled||(d.menu.length>0&&a(d.box).find("#node_"+w2utils.escapeId(b)).w2menu({items:d.menu,contextMenu:!0,originalEvent:c,onSelect:function(a){d.menuClick(b,parseInt(a.index),a.originalEvent)}}),c.preventDefault&&c.preventDefault(),d.trigger(a.extend(f,{phase:"after"}))))},menuClick:function(b,c,d){var e=this,f=e.trigger({phase:"before",type:"menuClick",target:b,originalEvent:d,menuIndex:c,menuItem:e.menu[c]});f.isCancelled!==!0&&e.trigger(a.extend(f,{phase:"after"}))},goFlat:function(){var b=this.trigger({phase:"before",type:"flat",goFlat:!this.flat});b.isCancelled!==!0&&(this.flat=!this.flat,this.refresh(),this.trigger(a.extend(b,{phase:"after"})))},render:function(b){var c=(new Date).getTime(),d=this,e=this.trigger({phase:"before",type:"render",target:this.name,box:b});if(e.isCancelled!==!0&&(null!=b&&(a(this.box).find("> div > div.w2ui-sidebar-div").length>0&&a(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-sidebar").html(""),this.box=b),this.box)){a(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-sidebar").html('
    '),a(this.box).find("> div").css({width:a(this.box).width()+"px",height:a(this.box).height()+"px"}),a(this.box).length>0&&(a(this.box)[0].style.cssText+=this.style);var f="";1==this.flatButton&&(f='
    "),""===this.topHTML&&""===f||(a(this.box).find(".w2ui-sidebar-top").html(this.topHTML+f),a(this.box).find(".w2ui-sidebar-div").css("top",a(this.box).find(".w2ui-sidebar-top").height()+"px")),""!==this.bottomHTML&&(a(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),a(this.box).find(".w2ui-sidebar-div").css("bottom",a(this.box).find(".w2ui-sidebar-bottom").height()+"px"));var g;return a(this.box).find("#sidebar_"+this.name+"_focus").on("focus",function(a){clearTimeout(g),d.hasFocus||d.focus(a)}).on("blur",function(a){g=setTimeout(function(){d.hasFocus&&d.blur(a)},100)}).on("keydown",function(a){9!=a.keyCode&&w2ui[d.name].keydown.call(w2ui[d.name],a)}),a(this.box).off("mousedown").on("mousedown",function(b){setTimeout(function(){if(["INPUT","TEXTAREA","SELECT"].indexOf(b.target.tagName.toUpperCase())==-1){var c=a(d.box).find("#sidebar_"+d.name+"_focus");if(!c.is(":focus")){if(a(b.target).hasClass("w2ui-node")){var e=a(b.target).position().top+a(d.box).find(".w2ui-sidebar-top").height()+b.offsetY;c.css({top:e+"px",left:"0px"})}c.focus()}}},1)}),this.trigger(a.extend(e,{phase:"after"})),this.refresh(),(new Date).getTime()-c}},refresh:function(b){function c(a){var b="",c=a.img;null==c&&(c=this.img);var d=a.icon;null==d&&(d=this.icon);for(var e=a.parent,f=0;e&&null!=e.parent;)e.group&&f--,e=e.parent,f++;if(null!=a.caption&&(a.text=a.caption),a.group)b='
    "+(a.groupShowHide&&a.collapsible?""+(!a.hidden&&a.expanded?w2utils.lang("Hide"):w2utils.lang("Show"))+"":"")+("function"==typeof a.text?a.text.call(j,a):""+a.text+"")+'
    ',j.flat&&(b='
     
    ');else{a.selected&&!a.disabled&&(j.selected=a.id),e="",c&&(e='
    '),d&&(e='
    ');var g=a.text;"function"==typeof a.text&&(g=a.text.call(j,a)),b='
    '+(a.nodes.length>0?a.expanded?"-":"+":a.plus?"+":"")+'
    '+e+(a.count||0===a.count?'
    '+a.count+"
    ":"")+'
    '+g+'
    ',j.flat&&(b='
    '+a.count+"":""))+"'), { id: '"+a.id+"', left: -5 })\" onmouseout=\"jQuery(this).find('.w2ui-node-data').w2tag(null, { id: '"+a.id+"' })\" ondblclick=\"w2ui['"+j.name+"'].dblClick('"+a.id+"', event);\" oncontextmenu=\"w2ui['"+j.name+"'].contextMenu('"+a.id+"', event);\" onClick=\"w2ui['"+j.name+"'].click('"+a.id+'\', event); ">
    '+e+'
    ')}return b}var d=(new Date).getTime(),e=this.trigger({phase:"before",type:"refresh",target:null!=b?b:this.name,fullRefresh:null==b});if(e.isCancelled!==!0){var f="";1==this.flatButton&&(f='
    "),""===this.topHTML&&""===f||(a(this.box).find(".w2ui-sidebar-top").html(this.topHTML+f),a(this.box).find(".w2ui-sidebar-div").css("top",a(this.box).find(".w2ui-sidebar-top").height()+"px")),""!==this.bottomHTML&&(a(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),a(this.box).find(".w2ui-sidebar-div").css("bottom",a(this.box).find(".w2ui-sidebar-bottom").height()+"px")),a(this.box).find("> div").removeClass("w2ui-sidebar-flat").addClass(this.flat?"w2ui-sidebar-flat":"").css({width:a(this.box).width()+"px",height:a(this.box).height()+"px"});var g,h,i,j=this;if(null==b)g=this,i=".w2ui-sidebar-div";else{if(g=this.get(b),null==g)return;i="#node_"+w2utils.escapeId(g.id)+"_sub"}var k;if(g!==this){var l="#node_"+w2utils.escapeId(g.id);k=c(g),a(this.box).find(l).before(''),a(this.box).find(l).remove(),a(this.box).find(i).remove(),a("#sidebar_"+this.name+"_tmp").before(k),a("#sidebar_"+this.name+"_tmp").remove()}a(this.box).find(i).html("");for(var m=0;m div").css({width:a(this.box).width()+"px",height:a(this.box).height()+"px"}),this.trigger(a.extend(c,{phase:"after"})),(new Date).getTime()-b},destroy:function(){var b=this.trigger({phase:"before",type:"destroy",target:this.name});b.isCancelled!==!0&&(a(this.box).find("> div > div.w2ui-sidebar-div").length>0&&a(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-sidebar").html(""),delete w2ui[this.name],this.trigger(a.extend(b,{phase:"after"})))},lock:function(a,b){var c=Array.prototype.slice.call(arguments,0);c.unshift(this.box),w2utils.lock.apply(window,c)},unlock:function(a){w2utils.unlock(this.box,a)}},a.extend(b.prototype,w2utils.event),w2obj.sidebar=b}(jQuery),function(a){var b=function(b){this.el=null,this.helpers={},this.type=b.type||"text",this.options=a.extend(!0,{},b),this.onSearch=b.onSearch||null,this.onRequest=b.onRequest||null,this.onLoad=b.onLoad||null,this.onError=b.onError||null,this.onClick=b.onClick||null,this.onAdd=b.onAdd||null,this.onNew=b.onNew||null,this.onRemove=b.onRemove||null,this.onMouseOver=b.onMouseOver||null,this.onMouseOut=b.onMouseOut||null,this.onIconClick=b.onIconClick||null,this.onScroll=b.onScroll||null,this.tmp={},delete this.options.type,delete this.options.onSearch,delete this.options.onRequest,delete this.options.onLoad,delete this.options.onError,delete this.options.onClick,delete this.options.onMouseOver,delete this.options.onMouseOut,delete this.options.onIconClick,delete this.options.onScroll,a.extend(!0,this,w2obj.field)};a.fn.w2field=function(c,d){if(0!==this.length){if(0===arguments.length){var e=a(this).data("w2field");return e}return"string"==typeof c&&"object"==typeof d&&(c=a.extend(!0,{},d,{type:c})),"string"==typeof c&&null==d&&(c={type:c}),c.type=String(c.type).toLowerCase(),this.each(function(d,e){var f=a(e).data("w2field");if(null==f){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}if(f.clear(),"clear"!=c.type){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}})}var f=b.prototype;if(f[c])return f[c].apply(f,Array.prototype.slice.call(arguments,1))},b.prototype={custom:{},addType:function(a,b){return a=String(a).toLowerCase(),this.custom[a]=b,!0},removeType:function(a){return a=String(a).toLowerCase(),!!this.custom[a]&&(delete this.custom[a],!0)},init:function(){var b,c=this,d=this.options;if("function"==typeof this.custom[this.type])return void this.custom[this.type].call(this,d);if(["INPUT","TEXTAREA"].indexOf(this.el.tagName.toUpperCase())==-1)return void console.log("ERROR: w2field could only be applied to INPUT or TEXTAREA.",this.el);switch(this.type){case"text":case"int":case"float":case"money":case"currency":case"percent":case"alphanumeric":case"bin":case"hex":b={min:null,max:null,step:1,autoFormat:!0,currencyPrefix:w2utils.settings.currencyPrefix,currencySuffix:w2utils.settings.currencySuffix,currencyPrecision:w2utils.settings.currencyPrecision,decimalSymbol:w2utils.settings.decimalSymbol,groupSymbol:w2utils.settings.groupSymbol,arrows:!1,keyboard:!0,precision:null,silent:!0,prefix:"",suffix:""},this.options=a.extend(!0,{},b,d),d=this.options,d.numberRE=new RegExp("["+d.groupSymbol+"]","g"),d.moneyRE=new RegExp("["+d.currencyPrefix+d.currencySuffix+d.groupSymbol+"]","g"),d.percentRE=new RegExp("["+d.groupSymbol+"%]","g"),["text","alphanumeric","hex","bin"].indexOf(this.type)!=-1&&(d.arrows=!1, +d.keyboard=!1),this.addPrefix(),this.addSuffix();break;case"color":b={prefix:"#",suffix:'
     
    ',arrows:!1,keyboard:!1,transparent:!0},a.extend(d,b),this.addPrefix(),this.addSuffix(),a(this.el).attr("maxlength",6),""!==a(this.el).val()&&setTimeout(function(){c.change()},1);break;case"date":b={format:w2utils.settings.dateFormat,keyboard:!0,silent:!0,start:"",end:"",blocked:{},colored:{},blockWeekDays:null},this.options=a.extend(!0,{},b,d),d=this.options,null==a(this.el).attr("placeholder")&&a(this.el).attr("placeholder",d.format);break;case"time":b={format:w2utils.settings.timeFormat,keyboard:!0,silent:!0,start:"",end:"",noMinutes:!1},this.options=a.extend(!0,{},b,d),d=this.options,null==a(this.el).attr("placeholder")&&a(this.el).attr("placeholder",d.format);break;case"datetime":b={format:w2utils.settings.dateFormat+" | "+w2utils.settings.timeFormat,keyboard:!0,silent:!0,start:"",end:"",blocked:[],colored:{},placeholder:null,btn_now:!0,noMinutes:!1},this.options=a.extend(!0,{},b,d),d=this.options,null==a(this.el).attr("placeholder")&&a(this.el).attr("placeholder",d.placeholder||d.format);break;case"list":case"combo":if(b={items:[],selected:{},url:null,recId:null,recText:null,method:null,interval:350,postData:{},minLength:1,cacheMax:250,maxDropHeight:350,maxDropWidth:null,match:"begins",silent:!0,icon:null,iconStyle:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onIconClick:null,renderDrop:null,compare:null,filter:!0,prefix:"",suffix:"",openOnFocus:!1,markSearch:!1},d.items=this.normMenu(d.items),"list"==this.type){if(b.openOnFocus=!0,a(this.el).addClass("w2ui-select"),!a.isPlainObject(d.selected)&&d.items)for(var e=0;e0?b.resize():clearInterval(c.sizeTimer)},200),a(b.el).data("tmp",c)},get:function(){var b;return b=["list","enum","file"].indexOf(this.type)!=-1?a(this.el).data("selected"):a(this.el).val()},set:function(b,c){if(["list","enum","file"].indexOf(this.type)!=-1){if("list"!=this.type&&c)null==a(this.el).data("selected")&&a(this.el).data("selected",[]),a(this.el).data("selected").push(b),a(this.el).change();else{var d="enum"==this.type?[b]:b;a(this.el).data("selected",d).change()}this.refresh()}else a(this.el).val(b)},setIndex:function(b,c){if(["list","enum"].indexOf(this.type)!=-1){var d=this.options.items;if(d&&d[b]){if("list"!=this.type&&c)null==a(this.el).data("selected")&&a(this.el).data("selected",[]),a(this.el).data("selected").push(d[b]),a(this.el).change();else{var e="enum"==this.type?[d[b]]:d[b];a(this.el).data("selected",e).change()}return this.refresh(),!0}}return!1},clear:function(){var b=this.options;["money","currency"].indexOf(this.type)!=-1&&a(this.el).val(a(this.el).val().replace(b.moneyRE,"")),"percent"==this.type&&a(this.el).val(a(this.el).val().replace(/%/g,"")),"color"==this.type&&a(this.el).removeAttr("maxlength"),"list"==this.type&&a(this.el).removeClass("w2ui-select"),this.type="clear";var c=a(this.el).data("tmp");if(this.tmp){null!=c&&(a(this.el).height("auto"),c&&c["old-padding-left"]&&a(this.el).css("padding-left",c["old-padding-left"]),c&&c["old-padding-right"]&&a(this.el).css("padding-right",c["old-padding-right"]),c&&c["old-background-color"]&&a(this.el).css("background-color",c["old-background-color"]),c&&c["old-border-color"]&&a(this.el).css("border-color",c["old-border-color"]),clearInterval(c.sizeTimer)),a(this.el).val(this.clean(a(this.el).val())).removeClass("w2field").removeData().off(".w2field");for(var d in this.helpers)a(this.helpers[d]).remove();this.helpers={}}},refresh:function(){var b=this,c=this.options,d=a(this.el).data("selected"),e=(new Date).getTime();if(["list"].indexOf(this.type)!=-1&&(a(b.el).parent().css("white-space","nowrap"),b.helpers.prefix&&b.helpers.prefix.hide(),setTimeout(function(){if(b.helpers.focus){!a.isEmptyObject(d)&&c.icon?(c.prefix='',b.addPrefix()):(c.prefix="",b.addPrefix());var e=b.helpers.focus.find("input");""===a(e).val()?(a(e).css("text-indent","-9999em").prev().css("opacity",0),a(b.el).val(d&&null!=d.text?w2utils.lang(d.text):"")):(a(e).css("text-indent",0).prev().css("opacity",1),a(b.el).val(""),setTimeout(function(){b.helpers.prefix&&b.helpers.prefix.hide();var d="position: absolute; opacity: 0; margin: 4px 0px 0px 2px; background-position: left !important;";c.icon?(a(e).css("margin-left","17px"),a(b.helpers.focus).find(".icon-search").attr("style",d+"width: 11px !important; opacity: 1; display: block")):(a(e).css("margin-left","0px"),a(b.helpers.focus).find(".icon-search").attr("style",d+"width: 0px !important; opacity: 0; display: none"))},1)),a(b.el).prop("readonly")||a(b.el).prop("disabled")?setTimeout(function(){a(b.helpers.prefix).css("opacity","0.6"),a(b.helpers.suffix).css("opacity","0.6")},1):setTimeout(function(){a(b.helpers.prefix).css("opacity","1"),a(b.helpers.suffix).css("opacity","1")},1)}},1)),["enum","file"].indexOf(this.type)!=-1){var f="";if(d)for(var g=0;g  '):'
      
    '+("enum"==b.type?h.text:h.name+' - '+w2utils.formatSize(h.size)+""),f+='
  • '+i+"
  • "}var j=b.helpers.multi,k=j.find("ul");if(j.attr("style",j.attr("style")+";"+c.style),a(b.el).css("z-index","-1"),a(b.el).prop("readonly")||a(b.el).prop("disabled")?setTimeout(function(){j[0].scrollTop=0,j.addClass("w2ui-readonly").find("li").css("opacity","0.9").parent().find("li.nomouse").hide().find("input").prop("readonly",!0).parents("ul").find(".w2ui-list-remove").hide()},1):setTimeout(function(){j.removeClass("w2ui-readonly").find("li").css("opacity","1").parent().find("li.nomouse").show().find("input").prop("readonly",!1).parents("ul").find(".w2ui-list-remove").show()},1),j.find(".w2ui-enum-placeholder").remove(),k.find("li").not("li.nomouse").remove(),""!==f)k.prepend(f);else if(null!=a(b.el).attr("placeholder")&&""===j.find("input").val()){var l="padding-top: "+a(this.el).css("padding-top")+";padding-left: "+a(this.el).css("padding-left")+"; box-sizing: "+a(this.el).css("box-sizing")+"; line-height: "+a(this.el).css("line-height")+"; font-size: "+a(this.el).css("font-size")+"; font-family: "+a(this.el).css("font-family")+"; ";j.prepend('
    '+a(b.el).attr("placeholder")+"
    ")}j.off("scroll.w2field").on("scroll.w2field",function(c){var d=b.trigger({phase:"before",type:"scroll",target:b.el,originalEvent:c});d.isCancelled!==!0&&b.trigger(a.extend(d,{phase:"after"}))}).find("li").data("mouse","out").on("click",function(c){var e="LI"==c.target.tagName.toUpperCase()?c.target:a(c.target).parents("LI"),f=d[a(e).attr("index")];if(!a(e).hasClass("nomouse"))if(c.stopPropagation(),a(c.target).hasClass("w2ui-list-remove")){if(a(b.el).prop("readonly")||a(b.el).prop("disabled"))return;var g=b.trigger({phase:"before",type:"remove",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;a().w2overlay(),d.splice(a(c.target).attr("index"),1),a(b.el).trigger("change"),a(c.target).parent().fadeOut("fast"),setTimeout(function(){b.refresh(),b.trigger(a.extend(g,{phase:"after"}))},300)}else{var g=b.trigger({phase:"before",type:"click",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;if("file"==b.type){var h="";/image/i.test(f.type)&&(h='
    ');var i='style="padding: 3px; text-align: right; color: #777;"',j='style="padding: 3px"';h+='
    "+w2utils.lang("Name")+":"+f.name+"
    "+w2utils.lang("Size")+":"+w2utils.formatSize(f.size)+"
    "+w2utils.lang("Type")+": '+f.type+"
    "+w2utils.lang("Modified")+":"+w2utils.date(f.modified)+"
    ",a("#w2ui-overlay").remove(),a(e).w2overlay(h)}b.trigger(a.extend(g,{phase:"after"}))}}).on("mouseover",function(c){var e="LI"==c.target.tagName.toUpperCase()?c.target:a(c.target).parents("LI");if(!a(e).hasClass("nomouse")){if("out"==a(e).data("mouse")){var f=d[a(c.target).attr("index")],g=b.trigger({phase:"before",type:"mouseOver",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}a(e).data("mouse","over")}}).on("mouseout",function(c){var e="LI"==c.target.tagName.toUpperCase()?c.target:a(c.target).parents("LI");a(e).hasClass("nomouse")||(a(e).data("mouse","leaving"),setTimeout(function(){if("leaving"==a(e).data("mouse")){a(e).data("mouse","out");var f=d[a(c.target).attr("index")],g=b.trigger({phase:"before",type:"mouseOut",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}},0))}),a(this.el).height("auto");var m=a(j).find("> div.w2ui-multi-items").height()+2*w2utils.getSize(j,"+height");m<26&&(m=26),m>c.maxHeight&&(m=c.maxHeight),j.length>0&&(j[0].scrollTop=1e3);var n=w2utils.getSize(a(this.el),"height")-2;if(n>m&&(m=n),a(j).css({height:m+"px",overflow:m==c.maxHeight?"auto":"hidden"}),m0)){var e=this.helpers.focus,f=this.helpers.multi,g=this.helpers.suffix,h=this.helpers.prefix;if(e&&e.width(a(b.el).width()),f){var i=w2utils.getSize(b.el,"width")-parseInt(a(b.el).css("margin-left"),10)-parseInt(a(b.el).css("margin-right"),10);a(f).width(i)}g&&(b.options.suffix='
    ',b.addSuffix()),h&&b.addPrefix(),b.tmp.current_width=c}},clean:function(b){if("number"==typeof b)return b;var c=this.options;return b=String(b).trim(),["int","float","money","currency","percent"].indexOf(this.type)!=-1&&("string"==typeof b&&(c.autoFormat&&["money","currency"].indexOf(this.type)!=-1&&(b=String(b).replace(c.moneyRE,"")),c.autoFormat&&"percent"==this.type&&(b=String(b).replace(c.percentRE,"")),c.autoFormat&&["int","float"].indexOf(this.type)!=-1&&(b=String(b).replace(c.numberRE,"")),b=b.replace(/\s+/g,"").replace(w2utils.settings.groupSymbol,"").replace(w2utils.settings.decimalSymbol,".")),parseFloat(b)==b&&(null!=c.min&&bc.max&&(b=c.max,a(this.el).val(c.max))),b=""!==b&&w2utils.isFloat(b)?Number(b):""),b},format:function(a){var b=this.options;if(b.autoFormat&&""!==a)switch(this.type){case"money":case"currency":a=w2utils.formatNumber(a,b.currencyPrecision,b.groupSymbol),""!==a&&(a=b.currencyPrefix+a+b.currencySuffix);break;case"percent":a=w2utils.formatNumber(a,b.precision,b.groupSymbol),""!==a&&(a+="%");break;case"float":a=w2utils.formatNumber(a,b.precision,b.groupSymbol);break;case"int":a=w2utils.formatNumber(a,0,b.groupSymbol)}return a},change:function(b){var c=this,d=c.options;if(["int","float","money","currency","percent"].indexOf(this.type)!=-1){var e=a(this.el).val(),f=this.format(this.clean(a(this.el).val()));if(""!==e&&e!=f)return a(this.el).val(f).change(),b.stopPropagation(),b.preventDefault(),!1}if("color"==this.type){var g="#"+a(this.el).val();6!=a(this.el).val().length&&3!=a(this.el).val().length&&(g=""),a(this.el).next().find("div").css("background-color",g),a(c.el).is(":focus")&&this.updateOverlay()}if(["list","enum","file"].indexOf(this.type)!=-1&&(c.refresh(),setTimeout(function(){c.refresh()},5)),["date","time","datetime"].indexOf(this.type)!=-1){var h=parseInt(c.el.value);w2utils.isInt(c.el.value)&&h>3e3&&("time"==this.type&&a(c.el).val(w2utils.formatTime(new Date(h),d.format)).change(),"date"==this.type&&a(c.el).val(w2utils.formatDate(new Date(h),d.format)).change(),"datetime"==this.type&&a(c.el).val(w2utils.formatDateTime(new Date(h),d.format)).change())}},click:function(b){b.stopPropagation(),["list","combo","enum"].indexOf(this.type)!=-1&&(a(this.el).is(":focus")||this.focus(b)),["date","time","color","datetime"].indexOf(this.type)!=-1&&this.updateOverlay()},focus:function(b){var c=this;this.options;if(["color","date","time","datetime"].indexOf(c.type)!==-1){if(a(c.el).prop("readonly")||a(c.el).prop("disabled"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){c.updateOverlay()},150)}if(["list","combo","enum"].indexOf(c.type)!=-1){if(a(c.el).prop("readonly")||a(c.el).prop("disabled"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),c.resize(),setTimeout(function(){return"list"==c.type&&a(c.el).is(":focus")?void a(c.helpers.focus).find("input").focus():(c.search(),void setTimeout(function(){c.updateOverlay()},1))},1)}"file"==c.type&&a(c.helpers.multi).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"})},blur:function(b){var c=this,d=c.options,e=a(c.el).val().trim();["color","date","time","list","combo","enum","datetime"].indexOf(c.type)!=-1&&a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),["int","float","money","currency","percent"].indexOf(c.type)!=-1&&(""===e||c.checkType(e)||(a(c.el).val("").change(),d.silent===!1&&(a(c.el).w2tag("Not a valid number"),setTimeout(function(){a(c.el).w2tag("")},3e3)))),["date","time","datetime"].indexOf(c.type)!=-1&&(""===e||c.inRange(c.el.value)?"date"!=c.type||""===e||w2utils.isDate(c.el.value,d.format)?"time"!=c.type||""===e||w2utils.isTime(c.el.value)?"datetime"!=c.type||""===e||w2utils.isDateTime(c.el.value,d.format)||(a(c.el).val("").removeData("selected").change(),d.silent===!1&&(a(c.el).w2tag("Not a valid date"),setTimeout(function(){a(c.el).w2tag("")},3e3))):(a(c.el).val("").removeData("selected").change(),d.silent===!1&&(a(c.el).w2tag("Not a valid time"),setTimeout(function(){a(c.el).w2tag("")},3e3))):(a(c.el).val("").removeData("selected").change(),d.silent===!1&&(a(c.el).w2tag("Not a valid date"),setTimeout(function(){a(c.el).w2tag("")},3e3))):(a(c.el).val("").removeData("selected").change(),d.silent===!1&&(a(c.el).w2tag("Not in range"),setTimeout(function(){a(c.el).w2tag("")},3e3)))),"enum"==c.type&&a(c.helpers.multi).find("input").val("").width(20),"file"==c.type&&a(c.helpers.multi).css({outline:"none"})},keyPress:function(a){var b=this;b.options;if(["int","float","money","currency","percent","hex","bin","color","alphanumeric"].indexOf(b.type)!=-1){if(a.metaKey||a.ctrlKey||a.altKey||a.charCode!=a.keyCode&&a.keyCode>0)return;var c=String.fromCharCode(a.charCode);if(!b.checkType(c,!0)&&13!=a.keyCode)return a.preventDefault(),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,!1}["date","time","datetime"].indexOf(b.type)!=-1&&9!==a.keyCode&&setTimeout(function(){b.updateOverlay()},1)},keyDown:function(b,c){var d=this,e=d.options,f=b.keyCode||c&&c.keyCode;if(["int","float","money","currency","percent"].indexOf(d.type)!=-1){if(!e.keyboard||a(d.el).prop("readonly")||a(d.el).prop("disabled"))return;var g=!1,h=parseFloat(a(d.el).val().replace(e.moneyRE,""))||0,i=e.step;switch((b.ctrlKey||b.metaKey)&&(i=10),f){case 38:if(b.shiftKey)break;a(d.el).val(h+i<=e.max||null==e.max?Number((h+i).toFixed(12)):e.max).change(),g=!0;break;case 40:if(b.shiftKey)break;a(d.el).val(h-i>=e.min||null==e.min?Number((h-i).toFixed(12)):e.min).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("date"==d.type){if(!e.keyboard||a(d.el).prop("readonly")||a(d.el).prop("disabled"))return;var g=!1,j=864e5,i=1;(b.ctrlKey||b.metaKey)&&(i=10);var k=w2utils.isDate(a(d.el).val(),e.format,!0);switch(k||(k=new Date,j=0),f){case 38:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()+j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()+1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0;break;case 40:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()-j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()-1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length),d.updateOverlay()},0))}if("time"==d.type){if(!e.keyboard||a(d.el).prop("readonly")||a(d.el).prop("disabled"))return;var g=!1,i=b.ctrlKey||b.metaKey?60:1,h=a(d.el).val(),m=d.toMin(h)||d.toMin((new Date).getHours()+":"+((new Date).getMinutes()-1));switch(f){case 38:if(b.shiftKey)break;m+=i,g=!0;break;case 40:if(b.shiftKey)break;m-=i,g=!0}g&&(a(d.el).val(d.fromMin(m)).change(),b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("datetime"==d.type){if(!e.keyboard||a(d.el).prop("readonly")||a(d.el).prop("disabled"))return;var g=!1,j=864e5,i=1;(b.ctrlKey||b.metaKey)&&(i=10);var n=a(d.el).val(),k=w2utils.isDateTime(n,this.options.format,!0);switch(k||(k=new Date,j=0),f){case 38:if(b.shiftKey)break;var l=w2utils.formatDateTime(k.getTime()+j,e.format);10==i&&(l=w2utils.formatDateTime(new Date(k.getFullYear(),k.getMonth()+1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0;break;case 40:if(b.shiftKey)break;var l=w2utils.formatDateTime(k.getTime()-j,e.format);10==i&&(l=w2utils.formatDateTime(new Date(k.getFullYear(),k.getMonth()-1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length),d.updateOverlay()},0))}if("color"==d.type){if(a(d.el).prop("readonly")||a(d.el).prop("disabled"))return;if(86==b.keyCode&&(b.ctrlKey||b.metaKey)&&(a(d.el).prop("maxlength",7),setTimeout(function(){var b=a(d).val();"#"==b.substr(0,1)&&(b=b.substr(1)),w2utils.isHex(b)||(b=""),a(d).val(b).prop("maxlength",6).change()},20)),(b.ctrlKey||b.metaKey)&&!b.shiftKey){var o=null,p=null;switch(f){case 38:o="up";break;case 40:o="down";break;case 39:o="right";break;case 37:o="left"}d.el.nav&&null!=o&&(p=d.el.nav(o),a(d.el).val(p).change(),b.preventDefault())}}if(["list","combo","enum"].indexOf(d.type)!=-1){if(a(d.el).prop("readonly")||a(d.el).prop("disabled"))return;var q=a(d.el).data("selected"),r=a(d.el),s=!1;switch(["list","enum"].indexOf(d.type)!=-1&&("list"==d.type&&(r=a(d.helpers.focus).find("input")),"enum"==d.type&&(r=a(d.helpers.multi).find("input")),[37,38,39,40].indexOf(f)==-1&&setTimeout(function(){d.refresh()},1),86==b.keyCode&&(b.ctrlKey||b.metaKey)&&setTimeout(function(){d.refresh(),d.search(),d.request()},50)),f){case 27:"list"==d.type&&(""!==r.val()&&r.val(""),b.stopPropagation());break;case 37:case 39:break;case 13:if(0===a("#w2ui-overlay").length)break;var t=e.items[e.index];if("enum"==d.type)if(null!=t){var u=d.trigger({phase:"before",type:"add",target:d.el,originalEvent:b.originalEvent,item:t});if(u.isCancelled===!0)return;t=u.item,q.length>=e.max&&e.max>0&&q.pop(),delete t.hidden,delete d.tmp.force_open,q.push(t),a(d.el).change(),r.val("").width(20),d.refresh(),d.trigger(a.extend(u,{phase:"after"}))}else{t={id:r.val(),text:r.val()};var u=d.trigger({phase:"before",type:"new",target:d.el,originalEvent:b.originalEvent,item:t});if(u.isCancelled===!0)return;t=u.item,"function"==typeof d.onNew&&(q.length>=e.max&&e.max>0&&q.pop(),delete d.tmp.force_open,q.push(t),a(d.el).change(),r.val("").width(20),d.refresh()),d.trigger(a.extend(u,{phase:"after"}))}else t&&a(d.el).data("selected",t).val(t.text).change(),""===a(d.el).val()&&a(d.el).data("selected")&&a(d.el).removeData("selected").val("").change(),"list"==d.type&&(r.val(""),d.refresh()),d.tmp.force_hide=!0;break;case 8:case 46:if("enum"==d.type&&8==f&&""===r.val()&&q.length>0){var t=q[q.length-1],u=d.trigger({phase:"before",type:"remove",target:d.el,originalEvent:b.originalEvent,item:t});if(u.isCancelled===!0)return;q.pop(),a(d.el).trigger("change"),d.refresh(),d.trigger(a.extend(u,{phase:"after"}))}"list"==d.type&&""===r.val()&&(a(d.el).data("selected",{}).change(),d.refresh());break;case 38:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):0,e.index--;e.index>0&&e.items[e.index].hidden;)e.index--;if(0===e.index&&e.items[e.index].hidden)for(;e.items[e.index]&&e.items[e.index].hidden;)e.index++;s=!0;break;case 40:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):-1,e.index++;e.index=e.items.length&&(e.index=e.items.length-1),d.updateOverlay(s),b.preventDefault(),void setTimeout(function(){if("enum"==d.type){var a=r.get(0);a.setSelectionRange(a.value.length,a.value.length)}else if("list"==d.type){var a=r.get(0);a.setSelectionRange(a.value.length,a.value.length)}else d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0);"enum"==d.type&&r.width(8*(r.val().length+2)+"px")}},keyUp:function(b){var c=this;if("color"==this.type&&86==b.keyCode&&(b.ctrlKey||b.metaKey)&&a(this).prop("maxlength",6),["list","combo","enum"].indexOf(this.type)!=-1){if(a(c.el).prop("readonly")||a(c.el).prop("disabled"))return;if([16,17,18,20,37,39,91].indexOf(b.keyCode)==-1){var d=a(this.helpers.focus).find("input");0===d.length&&(d=a(this.el));var e=this.trigger({phase:"before",type:"search",originalEvent:b,target:d,search:d.val()});if(e.isCancelled===!0)return;this.tmp.force_hide||this.request(),1==d.val().length&&this.refresh(),0!==a("#w2ui-overlay").length&&[38,40].indexOf(b.keyCode)!=-1||this.search(),this.trigger(a.extend(e,{phase:"after"}))}}},clearCache:function(){var a=this.options;a.items=[],this.tmp.xhr_loading=!1,this.tmp.xhr_search="",this.tmp.xhr_total=-1},request:function(b){var c=this,d=this.options,e=a(c.el).val()||"";if(d.url){if("enum"==c.type){var f=a(c.helpers.multi).find("input");e=0===f.length?"":f.val()}if("list"==c.type){var f=a(c.helpers.focus).find("input");e=0===f.length?"":f.val()}if(0!==d.minLength&&e.lengthc.tmp.xhr_search.length||e.length>=c.tmp.xhr_search.length&&e.substr(0,c.tmp.xhr_search.length)!=c.tmp.xhr_search||e.lengthd.cacheMax&&b.records.splice(d.cacheMax,1e5),null==d.recId&&null!=d.recid&&(d.recId=d.recid),(d.recId||d.recText)&&b.records.forEach(function(a){"string"==typeof d.recId&&(a.id=a[d.recId]),"function"==typeof d.recId&&(a.id=d.recId(a)),"string"==typeof d.recText&&(a.text=a[d.recText]),"function"==typeof d.recText&&(a.text=d.recText(a))}),c.tmp.xhr_loading=!1,c.tmp.xhr_search=e,c.tmp.xhr_total=b.records.length,d.items=c.normMenu(b.records),""===e&&0===b.records.length?c.tmp.emptySet=!0:c.tmp.emptySet=!1,c.search(),c.trigger(a.extend(i,{phase:"after"}))}}).fail(function(b,d,f){var g={status:d,error:f,rawResponseText:b.responseText},h=c.trigger({phase:"before",type:"error",target:c.el,search:e,error:g,xhr:b});if(h.isCancelled!==!0){if("abort"!=d){var i;try{i=a.parseJSON(b.responseText)}catch(a){}console.log("ERROR: Server communication failed.","\n EXPECTED:",{status:"success",records:[{id:1,text:"item"}]},"\n OR:",{status:"error",message:"error message"},"\n RECEIVED:","object"==typeof i?i:b.responseText)}c.clearCache(),c.search(),c.trigger(a.extend(h,{phase:"after"}))}}),c.trigger(a.extend(g,{phase:"after"}))}},b))}},search:function(){var b=this,c=this.options,d=a(b.el).val(),e=b.el,f=[],g=a(b.el).data("selected");if("enum"==b.type){e=a(b.helpers.multi).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}else if("list"==b.type){e=a(b.helpers.focus).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}if(b.tmp.xhr_loading!==!0){for(var i=0,j=0;j',{css:{"background-color":"#f5f5f5"}});var e,f,g=w2utils.isDate(a(c.el).val(),c.options.format,!0);g&&(e=g.getMonth()+1,f=g.getFullYear()),function b(d,e){a("#w2ui-overlay > div > div").html(c.getMonthHTML(d,e,a(c.el).val())),a("#w2ui-overlay .w2ui-calendar-title").on("mousedown",function(){if(a(this).next().hasClass("w2ui-calendar-jump"))a(this).next().remove();else{var d,e;a(this).after('
    '),a(this).next().hide().html(c.getYearHTML()).fadeIn(200),setTimeout(function(){a("#w2ui-overlay .w2ui-calendar-jump").find(".w2ui-jump-month, .w2ui-jump-year").on("click",function(){a(this).hasClass("w2ui-jump-month")&&(a(this).parent().find(".w2ui-jump-month").removeClass("selected"),a(this).addClass("selected"),e=a(this).attr("name")),a(this).hasClass("w2ui-jump-year")&&(a(this).parent().find(".w2ui-jump-year").removeClass("selected"),a(this).addClass("selected"),d=a(this).attr("name")),null!=d&&null!=e&&(a("#w2ui-overlay .w2ui-calendar-jump").fadeOut(100),setTimeout(function(){b(parseInt(e)+1,d)},100))}),a("#w2ui-overlay .w2ui-calendar-jump >:last-child").prop("scrollTop",2e3)},1)}}),a("#w2ui-overlay .w2ui-date").on("mousedown",function(){var b=a(this).attr("date");a(c.el).val(b).change(),a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"})}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)}),a("#w2ui-overlay .previous").on("mousedown",function(){var a=c.options.current.split("/");a[0]=parseInt(a[0])-1,b(a[0],a[1])}),a("#w2ui-overlay .next").on("mousedown",function(){var a=c.options.current.split("/");a[0]=parseInt(a[0])+1,b(a[0],a[1])})}(e,f)}if("time"==this.type){if(a(c.el).prop("readonly")||a(c.el).prop("disabled"))return;0===a("#w2ui-overlay").length&&a(c.el).w2overlay('
    ',{css:{"background-color":"#fff"}});var h="h24"==this.options.format;a("#w2ui-overlay > div").html(c.getHourHTML()),a("#w2ui-overlay .w2ui-time").on("mousedown",function(b){ +a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var d=a(this).attr("hour");a(c.el).val((d>12&&!h?d-12:d)+":00"+(h?"":d<12?" am":" pm")).change()}),null==this.options.noMinutes||this.options.noMinutes===!1?a("#w2ui-overlay .w2ui-time").on("mouseup",function(){var b=a(this).attr("hour");a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),a(c.el).w2overlay('
    ',{css:{"background-color":"#fff"}}),a("#w2ui-overlay > div").html(c.getMinHTML(b)),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var d=a(this).attr("min");a(c.el).val((b>12&&!h?b-12:b)+":"+(d<10?0:"")+d+(h?"":b<12?" am":" pm")).change()}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}):a("#w2ui-overlay .w2ui-time").on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}if("datetime"==this.type){if(a(c.el).prop("readonly")||a(c.el).prop("disabled"))return;a("#w2ui-overlay .w2ui-time").length>0&&a("#w2ui-overlay")[0].hide(),0===a("#w2ui-overlay").length&&a(c.el).w2overlay('
    ',{css:{"background-color":"#f5f5f5"}});var e,f,g=w2utils.isDateTime(a(c.el).val(),c.options.format,!0);g&&(e=g.getMonth()+1,f=g.getFullYear());var i=null;!function b(e,f){a("#w2ui-overlay > div > div").html(c.getMonthHTML(e,f,a(c.el).val())+(d.btn_now?'
    '+w2utils.lang("Current Date & Time")+"
    ":"")),a("#w2ui-overlay .w2ui-calendar-title").on("mousedown",function(){if(a(this).next().hasClass("w2ui-calendar-jump"))a(this).next().remove();else{var d,e;a(this).after('
    '),a(this).next().hide().html(c.getYearHTML()).fadeIn(200),setTimeout(function(){a("#w2ui-overlay .w2ui-calendar-jump").find(".w2ui-jump-month, .w2ui-jump-year").on("click",function(){a(this).hasClass("w2ui-jump-month")&&(a(this).parent().find(".w2ui-jump-month").removeClass("selected"),a(this).addClass("selected"),e=a(this).attr("name")),a(this).hasClass("w2ui-jump-year")&&(a(this).parent().find(".w2ui-jump-year").removeClass("selected"),a(this).addClass("selected"),d=a(this).attr("name")),null!=d&&null!=e&&(a("#w2ui-overlay .w2ui-calendar-jump").fadeOut(100),setTimeout(function(){b(parseInt(e)+1,d)},100))}),a("#w2ui-overlay .w2ui-calendar-jump >:last-child").prop("scrollTop",2e3)},1)}}),a("#w2ui-overlay .w2ui-date").on("mousedown",function(){var b=a(this).attr("date");a(c.el).val(b).change(),a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"}),i=new Date(a(this).attr("data-date"))}).on("mouseup",function(){var b,d;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),a(c.el).w2overlay('
    ',{css:{"background-color":"#fff"}});"h24"==c.options.format;a("#w2ui-overlay > div").html(c.getHourHTML()),a("#w2ui-overlay .w2ui-time").on("mousedown",function(d){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"}),b=a(this).attr("hour"),i.setHours(b);var e=w2utils.formatDateTime(i,c.options.format);a(c.el).val(e).change()}),null==c.options.noMinutes||c.options.noMinutes===!1?a("#w2ui-overlay .w2ui-time").on("mouseup",function(){var e=a(this).attr("hour");a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),a(c.el).w2overlay('
    ',{css:{"background-color":"#fff"}}),a("#w2ui-overlay > div").html(c.getMinHTML(e)),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"}),d=a(this).attr("min"),i.setHours(b,d);var e=w2utils.formatDateTime(i,c.options.format);a(c.el).val(e).change()}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}):a("#w2ui-overlay .w2ui-time").on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}),a("#w2ui-overlay .previous").on("mousedown",function(){var a=c.options.current.split("/");a[0]=parseInt(a[0])-1,b(a[0],a[1])}),a("#w2ui-overlay .next").on("mousedown",function(){var a=c.options.current.split("/");a[0]=parseInt(a[0])+1,b(a[0],a[1])}),a("#w2ui-overlay .now").on("mousedown",function(){var b=w2utils.formatDateTime(new Date,c.options.format);return a(c.el).val(b).change(),!1}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}(e,f)}if(["list","combo","enum"].indexOf(this.type)!=-1){var j=this.el,k=this.el;if("enum"==this.type&&(j=a(this.helpers.multi),k=a(j).find("input")),"list"==this.type){var l=a(k).data("selected");a.isPlainObject(l)&&!a.isEmptyObject(l)&&d.index==-1&&d.items.forEach(function(a,b){a.id==l.id&&(d.index=b)}),k=a(this.helpers.focus).find("input")}if(a(k).is(":focus")){if(d.openOnFocus===!1&&""===a(k).val()&&c.tmp.force_open!==!0)return void a().w2overlay();if(c.tmp.force_hide)return a().w2overlay(),void setTimeout(function(){delete c.tmp.force_hide},1);""!==a(k).val()&&delete c.tmp.force_open;var m=w2utils.lang("No matches");null!=d.url&&a(k).val().length=d.max&&d.max>0&&e.pop(),delete b.item.hidden,e.push(b.item),a(c.el).data("selected",e).change(),a(c.helpers.multi).find("input").val("").width(20),c.refresh(),a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),c.trigger(a.extend(f,{phase:"after"}))}}else a(c.el).data("selected",b.item).val(b.item.text).change(),c.helpers.focus&&c.helpers.focus.find("input").val("")}}))}}},inRange:function(b,c){var d=!1;if("date"==this.type){var e=w2utils.isDate(b,this.options.format,!0);if(e){if(this.options.start||this.options.end){var f="string"==typeof this.options.start?this.options.start:a(this.options.start).val(),g="string"==typeof this.options.end?this.options.end:a(this.options.end).val(),h=w2utils.isDate(f,this.options.format,!0),i=w2utils.isDate(g,this.options.format,!0),j=new Date(e);h||(h=j),i||(i=j),j>=h&&j<=i&&(d=!0)}else d=!0;if(this.options.blocked&&a.inArray(b,this.options.blocked)!=-1&&(d=!1),null!=this.options.blockWeekDays&&void 0!=this.options.blockWeekDays&&void 0!=this.options.blockWeekDays.length)for(var k=this.options.blockWeekDays.length,l=0;l=n&&m<=o&&(d=!0)}else d=!0;else if("datetime"==this.type){var e=w2utils.isDateTime(b,this.options.format,!0);if(e){if(this.options.start||this.options.end){var h,i;if("object"==typeof this.options.start&&this.options.start instanceof Date)h=this.options.start;else{var f="string"==typeof this.options.start?this.options.start:a(this.options.start).val();h=""!==f.trim()?w2utils.isDateTime(f,this.options.format,!0):""}if("object"==typeof this.options.end&&this.options.end instanceof Date)i=this.options.end;else{var g="string"==typeof this.options.end?this.options.end:a(this.options.end).val();i=""!==g.trim()?w2utils.isDateTime(g,this.options.format,!0):""}var j=e;h||(h=j),i||(i=j),c&&h instanceof Date&&(h.setHours(0),h.setMinutes(0),h.setSeconds(0)),j>=h&&j<=i&&(d=!0)}else d=!0;if(d&&this.options.blocked)for(var l=0;l'+b.options.prefix+""),c=a(b.el).prev(),c.css({color:a(b.el).css("color"),"font-family":a(b.el).css("font-family"),"font-size":a(b.el).css("font-size"),"padding-top":a(b.el).css("padding-top"),"padding-bottom":a(b.el).css("padding-bottom"),"padding-left":a(b.el).css("padding-left"),"padding-right":0,"margin-top":parseInt(a(b.el).css("margin-top"),10)+2+"px","margin-bottom":parseInt(a(b.el).css("margin-bottom"),10)+1+"px","margin-left":a(b.el).css("margin-left"),"margin-right":0}).on("click",function(c){if(b.options.icon&&"function"==typeof b.onIconClick){var d=b.trigger({phase:"before",type:"iconClick",target:b.el,el:a(this).find("span.w2ui-icon")[0]});if(d.isCancelled===!0)return;b.trigger(a.extend(d,{phase:"after"}))}else"list"==b.type?a(b.helpers.focus).find("input").focus():a(b.el).focus()}),a(b.el).css("padding-left",c.width()+parseInt(a(b.el).css("padding-left"),10)+"px"),b.helpers.prefix=c)}},1)},addSuffix:function(){var b,c,d=this;setTimeout(function(){if("clear"!==d.type){var e=a(d.el).data("tmp")||{};if(e["old-padding-right"]&&a(d.el).css("padding-right",e["old-padding-right"]),e["old-padding-right"]=a(d.el).css("padding-right"),a(d.el).data("tmp",e),c=parseInt(a(d.el).css("padding-right"),10),d.options.arrows){d.helpers.arrows&&a(d.helpers.arrows).remove(),a(d.el).after('
     
    ');w2utils.getSize(d.el,"height");b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),height:a(d.el).height()+parseInt(a(d.el).css("padding-top"),10)+parseInt(a(d.el).css("padding-bottom"),10)+"px",padding:0,"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":0,"border-left":"1px solid silver"}).css("margin-left","-"+(b.width()+parseInt(a(d.el).css("margin-right"),10)+12)+"px").on("mousedown",function(b){function c(){clearTimeout(f.data("_field_update_timer")),f.off("mouseup",c)}function e(c){a(d.el).focus(),d.keyDown(a.Event("keydown"),{keyCode:"up"==a(b.target).attr("type")?38:40}),c!==!1&&a("body").data("_field_update_timer",setTimeout(e,60))}var f=a("body");f.on("mouseup",c),f.data("_field_update_timer",setTimeout(e,700)),e(!1)}),c+=b.width()+12,a(d.el).css("padding-right",c+"px"),d.helpers.arrows=b}""!==d.options.suffix&&(d.helpers.suffix&&a(d.helpers.suffix).remove(),a(d.el).after('
    '+d.options.suffix+"
    "),b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),"padding-top":a(d.el).css("padding-top"),"padding-bottom":a(d.el).css("padding-bottom"),"padding-left":"3px","padding-right":a(d.el).css("padding-right"),"margin-top":parseInt(a(d.el).css("margin-top"),10)+2+"px","margin-bottom":parseInt(a(d.el).css("margin-bottom"),10)+1+"px"}).on("click",function(b){"list"==d.type?a(d.helpers.focus).find("input").focus():a(d.el).focus()}),b.css("margin-left","-"+(w2utils.getSize(b,"width")+parseInt(a(d.el).css("margin-right"),10)+2)+"px"),c+=b.width()+3,a(d.el).css("padding-right",c+"px"),d.helpers.suffix=b)}},1)},addFocus:function(){var b,c=this,d=(this.options,0);a(c.helpers.focus).remove();var e=a(c.el).attr("tabIndex");e&&e!=-1&&(c.el._tabIndex=e),c.el._tabIndex&&(e=c.el._tabIndex),null==e&&(e=-1);var f='
    ';a(c.el).attr("tabindex",-1).before(f);var g=a(c.el).prev();c.helpers.focus=g,g.css({width:a(c.el).width(),"margin-top":a(c.el).css("margin-top"),"margin-left":parseInt(a(c.el).css("margin-left"))+parseInt(a(c.el).css("padding-left"))+"px","margin-bottom":a(c.el).css("margin-bottom"),"margin-right":a(c.el).css("margin-right")}).find("input").css({cursor:"default",width:"100%",outline:"none",opacity:1,margin:0,border:"1px solid transparent",padding:a(c.el).css("padding-top"),"padding-left":0,"margin-left":d>0?d+6:0,"background-color":"transparent"}),g.find("input").on("click",function(b){0===a("#w2ui-overlay").length&&c.focus(b),b.stopPropagation()}).on("focus",function(d){b=a(c.el).attr("placeholder"),a(c.el).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(this).val(""),a(c.el).triggerHandler("focus"),d.stopPropagation?d.stopPropagation():d.cancelBubble=!0}).on("blur",function(d){a(c.el).css("outline","none"),a(this).val(""),c.refresh(),a(c.el).triggerHandler("blur"),d.stopPropagation?d.stopPropagation():d.cancelBubble=!0,null!=b&&a(c.el).attr("placeholder",b)}).on("keydown",function(d){var e=this;c.keyDown(d),setTimeout(function(){""===e.value?a(c.el).attr("placeholder",b):a(c.el).attr("placeholder","")},10)}).on("keyup",function(a){c.keyUp(a)}).on("keypress",function(a){c.keyPress(a)}),g.on("click",function(b){a(this).find("input").focus()}),c.refresh()},addMulti:function(){var b=this;this.options;a(b.helpers.multi).remove();var c="",d="margin-top : 0px; margin-bottom : 0px; margin-left : "+a(b.el).css("margin-left")+"; margin-right : "+a(b.el).css("margin-right")+"; width : "+(w2utils.getSize(b.el,"width")-parseInt(a(b.el).css("margin-left"),10)-parseInt(a(b.el).css("margin-right"),10))+"px;";if("enum"==b.type){var e=a(b.el).attr("tabIndex");e&&e!=-1&&(b.el._tabIndex=e),b.el._tabIndex&&(e=b.el._tabIndex),null==e&&(e=-1),c='
    '}"file"==b.type&&(c='
    ');var f=a(b.el).data("tmp")||{};f["old-background-color"]=a(b.el).css("background-color"),f["old-border-color"]=a(b.el).css("border-color"),a(b.el).data("tmp",f),a(b.el).before(c).css({"background-color":"transparent","border-color":"transparent"});var g=a(b.el).prev();b.helpers.multi=g,"enum"==b.type&&(a(b.el).attr("tabindex",-1),g.find("input").on("click",function(c){0===a("#w2ui-overlay").length&&b.focus(c),a(b.el).triggerHandler("click")}).on("focus",function(c){a(g).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(g).css("outline","none"),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){b.keyPress(a)}),g.on("click",function(b){a(this).find("input").focus()})),"file"==b.type&&(a(b.el).css("outline","none"),g.on("click",function(c){a(b.el).focus(),a(b.el).prop("readonly")||a(b.el).prop("disabled")||(b.blur(c),b.resize(),setTimeout(function(){g.find("input").click()},10))}).on("dragenter",function(c){a(b.el).prop("readonly")||a(b.el).prop("disabled")||a(g).addClass("w2ui-file-dragover")}).on("dragleave",function(c){if(!a(b.el).prop("readonly")&&!a(b.el).prop("disabled")){var d=a(c.target).parents(".w2ui-field-helper");0===d.length&&a(g).removeClass("w2ui-file-dragover")}}).on("drop",function(c){if(!a(b.el).prop("readonly")&&!a(b.el).prop("disabled")){a(g).removeClass("w2ui-file-dragover");for(var d=c.originalEvent.dataTransfer.files,e=0,f=d.length;ee.maxFileSize)return c="Maximum file size is "+w2utils.formatSize(e.maxFileSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(0!==e.maxSize&&h+g.size>e.maxSize)return c="Maximum total size is "+w2utils.formatSize(e.maxSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(0!==e.max&&i>=e.max)return c="Maximum number of files is "+e.max,e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(f.push(g),"undefined"!=typeof FileReader&&e.readContent===!0){var l=new FileReader;l.onload=function(){return function(b){var c=b.target.result,e=c.indexOf(",");g.content=c.substr(e+1),d.refresh(),a(d.el).trigger("change"),d.trigger(a.extend(k,{phase:"after"}))}}(),l.readAsDataURL(b)}else d.refresh(),a(d.el).trigger("change")}},normMenu:function(b){if(a.isArray(b)){for(var c=0;c12&&(a-=12,b++),(a<1||0===a)&&(a+=12,b--),b/4==Math.floor(b/4)?f[1]="29":f[1]="28",j.current=a+"/"+b,d=new Date(b,a-1,1);for(var k=d.getDay(),l="",m=0;m'+i[m]+"";var n='
    '+e[a-1]+", "+b+'
    '+l+"",o=1;if("M"!=w2utils.settings.weekStarts&&k++,"datetime"===this.type){var p=w2utils.isDateTime(c,j.format,!0);c=w2utils.formatDate(p,w2utils.settings.dateFormat)}for(var q=1;q<43;q++){if(0===k&&1==q){for(var r=0;r<6;r++)n+='';q+=6}else if(qf[a-1]){n+='',q%7===0&&(n+="");continue}var s=b+"/"+a+"/"+o,t=new Date(s),u="";6===t.getDay()&&(u=" w2ui-saturday"),0===t.getDay()&&(u=" w2ui-sunday"),s==g&&(u+=" w2ui-today");var v,w,x=o,y="",z="";if("datetime"===this.type?(v=w2utils.formatDateTime(s,j.format),w=w2utils.formatDate(s,w2utils.settings.dateFormat)):(v=w2utils.formatDate(s,j.format),w=v),j.colored&&void 0!==j.colored[w]){var A=j.colored[w].split(":");z="background-color: "+A[0]+";",y="color: "+A[1]+";"}n+='",(q%7===0||0===k&&1==q)&&(n+=""),o++}return n+="
      
    '+x+"
    "},getYearHTML:function(){for(var a=w2utils.settings.shortmonths,b=w2utils.settings.dateStartYear,c=w2utils.settings.dateEndYear,d="",e="",f=0;f'+a[f]+"";for(var g=b;g<=c;g++)e+='
    '+g+"
    ";return"
    "+d+"
    "+e+"
    "},getHourHTML:function(){var a=[],b=this.options;null==b&&(b={format:w2utils.settings.timeFormat});for(var c=b.format.indexOf("h24")>-1,d=0;d<24;d++){var e=(d>=12&&!c?d-12:d)+":00"+(c?"":d<12?" am":" pm");12!=d||c||(e="12:00 pm"),a[Math.floor(d/8)]||(a[Math.floor(d/8)]="");var f=this.fromMin(this.toMin(e)),g=this.fromMin(this.toMin(e)+59);if("datetime"===this.type){var h=w2utils.isDateTime(this.el.value,b.format,!0),i=b.format.split("|")[0].trim();f=w2utils.formatDate(h,i)+" "+f,g=w2utils.formatDate(h,i)+" "+g}a[Math.floor(d/8)]+='
    '+e+"
    "}var j='
    '+w2utils.lang("Select Hour")+'
    '+a[0]+" "+a[1]+" "+a[2]+"
    ";return j},getMinHTML:function(a){null==a&&(a=0);var b=this.options;null==b&&(b={format:w2utils.settings.timeFormat});for(var c=b.format.indexOf("h24")>-1,d=[],e=0;e<60;e+=5){var f=(a>12&&!c?a-12:a)+":"+(e<10?0:"")+e+" "+(c?"":a<12?"am":"pm"),g=f,h=e<20?0:e<40?1:2;if(d[h]||(d[h]=""),"datetime"===this.type){var i=w2utils.isDateTime(this.el.value,b.format,!0),j=b.format.split("|")[0].trim();g=w2utils.formatDate(i,j)+" "+g}d[h]+='
    '+f+"
    "}var k='
    '+w2utils.lang("Select Minute")+'
    '+d[0]+" "+d[1]+" "+d[2]+"
    ";return k},toMin:function(a){if("string"!=typeof a)return null;var b=a.split(":");return 2!==b.length?null:(b[0]=parseInt(b[0]),b[1]=parseInt(b[1]),a.indexOf("pm")!=-1&&12!=b[0]&&(b[0]+=12),60*b[0]+b[1])},fromMin:function(a){var b="";a>=1440&&(a%=1440),a<0&&(a=1440+a);var c=Math.floor(a/60),d=(a%60<10?"0":"")+a%60,e=this.options;return null==e&&(e={format:w2utils.settings.timeFormat}),b=e.format.indexOf("h24")!=-1?c+":"+d:(c<=12?c:c-12)+":"+d+" "+(c>=12?"pm":"am")}},a.extend(b.prototype,w2utils.event),w2obj.field=b}(jQuery),function($){var w2form=function(a){this.name=null,this.header="",this.box=null,this.url="",this.routeData={},this.formURL="",this.formHTML="",this.page=0,this.recid=0,this.fields=[],this.actions={},this.record={},this.original={},this.postData={},this.httpHeaders={},this.method=null,this.toolbar={},this.tabs={},this.style="",this.focus=0,this.isGenerated=!1,this.last={xhr:null},$.extend(!0,this,w2obj.form,a)};$.fn.w2form=function(a){if($.isPlainObject(a)){var b=this;if(!w2utils.checkName(a,"w2form"))return;var c=a.record,d=a.original,e=a.fields,f=a.toolbar,g=a.tabs,h=new w2form(a);if($.extend(h,{record:{},original:{},fields:[],tabs:{},toolbar:{},handlers:[]}),$.isArray(g)){$.extend(!0,h.tabs,{tabs:[]});for(var i=0;i0&&(h.box=b[0]),""!==h.formURL?$.get(h.formURL,function(a){h.formHTML=a,h.isGenerated=!0,0===$(h.box).length&&0===a.length||($(h.box).html(a),h.render(h.box))}):""!==h.formHTML||(0!==$(this).length&&""!==$.trim($(this).html())?h.formHTML=$(this).html():h.formHTML=h.generateHTML()),w2ui[h.name]=h,""===h.formURL&&(String(h.formHTML).indexOf("w2ui-page")==-1&&(h.formHTML='
    '+h.formHTML+"
    "),$(h.box).html(h.formHTML),h.isGenerated=!0,h.render(h.box)),h}var b=w2ui[$(this).attr("name")];return b?arguments.length>0?(b[a]&&b[a].apply(b,Array.prototype.slice.call(arguments,1)),this):b:null},w2form.prototype={onRequest:null,onLoad:null,onValidate:null,onSubmit:null,onProgress:null,onSave:null,onChange:null,onRender:null,onRefresh:null,onResize:null,onDestroy:null,onAction:null,onToolbar:null,onError:null,msgNotJSON:"Returned data is not in valid JSON format.",msgAJAXerror:"AJAX error. See console for more details.",msgRefresh:"Refreshing...",msgSaving:"Saving...",get:function(a,b){if(0===arguments.length){for(var c=[],d=0;d0&&this.refresh(),a},hide:function(){for(var a=0,b=0;b0&&this.refresh(),a},enable:function(){for(var a=0,b=0;b0&&this.refresh(),a},disable:function(){for(var a=0,b=0;b0&&this.refresh(),a},reload:function(a){var b="object"!=typeof this.url?this.url:this.url.get;b&&0!==this.recid&&null!=this.recid?this.request(a):"function"==typeof a&&a()},clear:function(){this.recid=0,this.record={},$().w2tag(),this.refresh()},error:function(a){var b=this,c=this.trigger({target:this.name,type:"error",message:a,xhr:this.last.xhr});return c.isCancelled===!0?void("function"==typeof callBack&&callBack()):(setTimeout(function(){b.message(a)},1),void this.trigger($.extend(c,{phase:"after"})))},message:function(a){"string"==typeof a&&(a={width:a.length<300?350:550,height:a.length<300?170:250,body:'
    '+a+"
    ",buttons:'",onOpen:function(a){setTimeout(function(){$(a.box).find(".w2ui-btn").focus()},25)}}),w2utils.message.call(this,{box:this.box,path:"w2ui."+this.name,title:".w2ui-form-header:visible",body:".w2ui-form-box"},a)},validate:function(a){null==a&&(a=!0),$().w2tag();for(var b=[],c=0;c0)for(var k=0;k
    '),setTimeout(function(){var params={};params.cmd="save",params.recid=obj.recid,params.name=obj.name,$.extend(params,obj.postData),$.extend(params,postData),obj.fields.forEach(function(a){"file"==a.type&&Array.isArray(obj.record[a.field])&&obj.record[a.field].forEach(function(a){delete a.file})}),params.record=$.extend(!0,{},obj.record);var edata=obj.trigger({phase:"before",type:"submit",target:obj.name,url:obj.url,postData:params,httpHeaders:obj.httpHeaders});if(edata.isCancelled!==!0){var url=edata.url;if("object"==typeof edata.url&&edata.url.save&&(url=edata.url.save),obj.last.xhr)try{obj.last.xhr.abort()}catch(a){}if(!$.isEmptyObject(obj.routeData)){var info=w2utils.parseRoute(url);if(info.keys.length>0)for(var k=0;k';switch(g.type){case"pass":case"password":h='';break;case"checkbox":h='';break;case"radio":h="";var i=g.options.items?g.options.items:g.html.items;$.isArray(i)||(i=[]),i.length>0&&(i=w2obj.field.prototype.normMenu(i));for(var j=0;j '+i[j].text+"
    ";break;case"select":h='";break;case"textarea":h='';break;case"toggle":h='
    ';break;case"html":case"custom":case"empty":h=""}""!==e&&(a!=g.html.page||b!=g.html.column||g.html.group&&e!=g.html.group)&&(d[a][b]+="\n ",e=""),g.html.group&&e!=g.html.group&&(c+='\n
    '+g.html.group+'
    \n
    ',e=g.html.group),c+='\n
    \n \n
    "+h+w2utils.lang(g.html.text)+"
    \n
    ",null==d[g.html.page]&&(d[g.html.page]=[]),null==d[g.html.page][g.html.column]&&(d[g.html.page][g.html.column]=""),d[g.html.page][g.html.column]+=c,a=g.html.page,b=g.html.column}if(""!==e&&(d[a][b]+="\n
    "),this.tabs.tabs)for(var j=0;j'+w2utils.lang(n.caption)+""}k+="\n"}c="";for(var o=0;o
    ';for(var p=0;p'+(d[o][p]||"")+"\n
    ";c+="\n"}return c+=k},action:function(a,b){var c=this.actions[a],d=c;$.isPlainObject(c)&&c.onClick&&(d=c.onClick);var e=this.trigger({phase:"before",target:a,type:"action",click:d,originalEvent:b});e.isCancelled!==!0&&("function"==typeof d&&d.call(this,b),this.trigger($.extend(e,{phase:"after"})))},resize:function(){function a(){d.width($(b.box).width()).height($(b.box).height()),f.css("top",""!==b.header?w2utils.getSize(e,"height"):0),g.css("top",(""!==b.header?w2utils.getSize(e,"height"):0)+("object"==typeof b.toolbar&&$.isArray(b.toolbar.items)&&b.toolbar.items.length>0?w2utils.getSize(f,"height"):0)),h.css("top",(""!==b.header?w2utils.getSize(e,"height"):0)+("object"==typeof b.toolbar&&$.isArray(b.toolbar.items)&&b.toolbar.items.length>0?w2utils.getSize(f,"height")+5:0)+("object"==typeof b.tabs&&$.isArray(b.tabs.tabs)&&b.tabs.tabs.length>0?w2utils.getSize(g,"height")+5:0)),h.css("bottom",k.length>0?w2utils.getSize(k,"height"):0)}var b=this,c=this.trigger({phase:"before",target:this.name,type:"resize"});if(c.isCancelled!==!0){var d=$(this.box).find("> div.w2ui-form-box"),e=$(this.box).find("> div .w2ui-form-header"),f=$(this.box).find("> div .w2ui-form-toolbar"),g=$(this.box).find("> div .w2ui-form-tabs"),h=$(this.box).find("> div .w2ui-page"),i=$(this.box).find("> div .w2ui-page.page-"+this.page),j=$(this.box).find("> div .w2ui-page.page-"+this.page+" > div"),k=$(this.box).find("> div .w2ui-buttons");a(),0!==parseInt($(this.box).height())&&$(this.box).data("auto-size")!==!0||($(this.box).height((e.length>0?w2utils.getSize(e,"height"):0)+("object"==typeof this.tabs&&$.isArray(this.tabs.tabs)&&this.tabs.tabs.length>0?w2utils.getSize(g,"height"):0)+("object"==typeof this.toolbar&&$.isArray(this.toolbar.items)&&this.toolbar.items.length>0?w2utils.getSize(f,"height"):0)+(h.length>0?w2utils.getSize(j,"height")+w2utils.getSize(i,"+height")+12:0)+(k.length>0?w2utils.getSize(k,"height"):0)),$(this.box).data("auto-size",!0)),a(),this.toolbar&&this.toolbar.resize&&this.toolbar.resize(),this.tabs&&this.tabs.resize&&this.tabs.resize(),b.trigger($.extend(c,{phase:"after"}))}},refresh:function(a){var b=(new Date).getTime(),c=this;if(this.box&&this.isGenerated&&null!=$(this.box).html()){var d=this.trigger({phase:"before",target:this.name,type:"refresh",page:this.page,field:a});if(d.isCancelled!==!0){if(null!=a)var e=c.get(a,!0),f=e+1;else{$(this.box).find("input, textarea, select").each(function(a,b){var d=null!=$(b).attr("name")?$(b).attr("name"):$(b).attr("id"),e=c.get(d);if(e){var f=$(b).parents(".w2ui-page");if(f.length>0)for(var g=0;g<100;g++)if(f.hasClass("page-"+g)){e.page=g;break}}}),$(this.box).find(".w2ui-page").hide(),$(this.box).find(".w2ui-page.page-"+this.page).show(),$(this.box).find(".w2ui-form-header").html(this.header),"object"==typeof this.tabs&&$.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()):$("#form_"+this.name+"_tabs").hide(),"object"==typeof this.toolbar&&$.isArray(this.toolbar.items)&&this.toolbar.items.length>0?($("#form_"+this.name+"_toolbar").show(),this.toolbar.refresh()):$("#form_"+this.name+"_toolbar").hide();var e=0,f=this.fields.length}for(var g=e;g0){var j=$(d.el).data("w2field").helpers.multi;$(j).removeClass("w2ui-error")}(""===i||null==i||$.isArray(i)&&0===i.length||$.isPlainObject(i)&&$.isEmptyObject(i))&&(i=null),c.record[this.name]=i,c.trigger($.extend(h,{phase:"after"}))}}),a.required?$(a.el).parent().parent().addClass("w2ui-required"):$(a.el).parent().parent().removeClass("w2ui-required"),null!=a.disabled&&(a.disabled?$(a.el).prop("readonly",!0):$(a.el).prop("readonly",!1)),a.hidden?$(a.el).parent().parent().hide():$(a.el).parent().parent().show()}$(this.box).find("button, input[type=button]").each(function(a,b){$(b).off("click").on("click",function(a){var b=this.value;this.id&&(b=this.id),this.name&&(b=this.name),c.action(b,a)})});for(var g=e;g0&&!$.isPlainObject(k[0])&&(a.options.items=w2obj.field.prototype.normMenu(k));for(var l=0;l0){k=w2obj.field.prototype.normMenu(k),$(a.el).html("");for(var n=0;n'+k[n].text+" *").length>1&&$(h[l]).wrapInner("
    ");return this.trigger($.extend(d,{phase:"after"})),this.resize(),(new Date).getTime()-b}}},render:function(a){function b(){var a=$(d.box).find("div:not(.w2ui-field-helper) > input, select, textarea, div > label:nth-child(1) > :radio").not(".file-input");a.length>d.focus&&a[d.focus].focus()}var c=(new Date).getTime(),d=this;if("object"==typeof a&&($(this.box).find("#form_"+this.name+"_tabs").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-form").html(""),this.box=a),this.isGenerated&&this.box){var e=this.trigger({phase:"before",target:this.name,type:"render",box:null!=a?a:this.box});if(e.isCancelled!==!0){$.isEmptyObject(this.original)&&!$.isEmptyObject(this.record)&&(this.original=$.extend(!0,{},this.record));var f='
    '+(""!==this.header?'
    '+this.header+"
    ":"")+' '+this.formHTML+"
    ";$(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-form").html(f),$(this.box).length>0&&($(this.box)[0].style.cssText+=this.style),"function"!=typeof this.toolbar.render&&(this.toolbar=$().w2toolbar($.extend({},this.toolbar,{name:this.name+"_toolbar",owner:this})),this.toolbar.on("click",function(a){var b=d.trigger({phase:"before",type:"toolbar",target:a.target,originalEvent:a});b.isCancelled!==!0&&d.trigger($.extend(b,{phase:"after"}))})),"object"==typeof this.toolbar&&"function"==typeof this.toolbar.render&&this.toolbar.render($("#form_"+this.name+"_toolbar")[0]),"function"!=typeof this.tabs.render&&(this.tabs=$().w2tabs($.extend({},this.tabs,{name:this.name+"_tabs",owner:this,active:this.tabs.active})),this.tabs.on("click",function(a){d.goto(this.get(a.target,!0))})),"object"==typeof this.tabs&&"function"==typeof this.tabs.render&&(this.tabs.render($("#form_"+this.name+"_tabs")[0]),this.tabs.active&&this.tabs.click(this.tabs.active)),this.trigger($.extend(e,{phase:"after"})),this.resize();var g="object"!=typeof this.url?this.url:this.url.get;return g&&0!==this.recid&&null!=this.recid?this.request():this.refresh(),0===$(".w2ui-layout").length&&(this.tmp_resize=function(a){w2ui[d.name].resize()},$(window).off("resize","body").on("resize","body",this.tmp_resize)),this.focus>=0&&setTimeout(function(){0===$(d.box).find("input, select, textarea").length?setTimeout(b,500):b()},10),(new Date).getTime()-c}}},destroy:function(){var a=this.trigger({phase:"before",target:this.name,type:"destroy"});a.isCancelled!==!0&&("object"==typeof this.toolbar&&this.toolbar.destroy&&this.toolbar.destroy(),"object"==typeof this.tabs&&this.tabs.destroy&&this.tabs.destroy(),$(this.box).find("#form_"+this.name+"_tabs").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-form").html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})),$(window).off("resize","body"))}},$.extend(w2form.prototype,w2utils.event),w2obj.form=w2form}(jQuery); \ No newline at end of file diff --git a/src/platform/verilog.ts b/src/platform/verilog.ts index a2103248..52ee6310 100644 --- a/src/platform/verilog.ts +++ b/src/platform/verilog.ts @@ -585,6 +585,10 @@ var VerilogPlatform = function(mainElement, options) { this.poweron(); // query output this.hasvideo = gen.vsync !== undefined && gen.hsync !== undefined && gen.rgb !== undefined; + if (this.hasvideo) { + const IGNORE_SIGNALS = ['clk','reset']; + trace_signals = trace_signals.filter((v) => { return IGNORE_SIGNALS.indexOf(v.name)<0; }); // remove clk, reset + } } } // replace program ROM, if using the assembler @@ -607,7 +611,7 @@ var VerilogPlatform = function(mainElement, options) { this.waveview = null; } } - + restartAudio() { // stop/start audio var hasAudio = gen && gen.spkr !== undefined && frameRate > 1; diff --git a/src/waveform.ts b/src/waveform.ts index 65a934d5..4138eb7b 100644 --- a/src/waveform.ts +++ b/src/waveform.ts @@ -156,7 +156,7 @@ export class WaveformView { } setZoom(zoom : number) { - this.zoom = Math.max(1, zoom); + this.zoom = Math.max(1, Math.min(64, zoom)); this.clocksPerPage = Math.ceil(this.pageWidth/this.zoom); // TODO: refactor into other one this.refresh(); } @@ -181,19 +181,30 @@ export class WaveformView { // clear to black ctx.clearRect(0, 0, canvas.width, canvas.height); // draw waveform - ctx.strokeStyle = "#66ff66"; - var b = 4; - var h2 = h-16-b; + ctx.strokeStyle = ctx.fillStyle = "#66ff66"; + var fh = 12; + var b1 = fh+4; + var b2 = 4; + var h2 = h-b1-b2; var yrange = ((1< 1 && this.zoom >= 32; + var ycen = b1+h2-1; + // draw waveform ctx.beginPath(); var x = 0; var y = 0; + var lastval = -1; for (var i=0; i0) ctx.lineTo(x,y); - y = b + (1.0 - data[i]/yrange) * h2; + y = b1 + (1.0 - val/yrange) * h2; if (!isclk) x += this.zoom*(1/8); if (i==0) ctx.moveTo(x,y); @@ -217,7 +228,7 @@ export class WaveformView { var val = data[this.tsel - this.t0]; ctx.textAlign = 'right'; if (val !== undefined) { - ctx.fillText(val.toString(), w-b*2, h); + ctx.fillText(val.toString(), w-fh, ycen); } } // draw labels @@ -225,7 +236,7 @@ export class WaveformView { ctx.textAlign = "left"; var name = meta.name; name = name.replace(/__DOT__/g, "."); // make nicer name - ctx.fillText(name, 5, h-b); + ctx.fillText(name, 5, fh); } }