1 // Copyright (C) 2005 Rod Roark <rod@sunsetsystems.com>
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
8 // open a new cascaded window
9 function cascwin(url, winname, width, height, options) {
10 var mywin = window.parent ? window.parent : window;
11 var newx = 25, newy = 25;
12 if (!isNaN(mywin.screenX)) {
13 newx += mywin.screenX;
14 newy += mywin.screenY;
15 } else if (!isNaN(mywin.screenLeft)) {
16 newx += mywin.screenLeft;
17 newy += mywin.screenTop;
19 if ((newx + width) > screen.width || (newy + height) > screen.height) {
25 // MS IE version detection taken from
26 // http://msdn2.microsoft.com/en-us/library/ms537509.aspx
27 // to adjust the height of this box for IE only -- JRM
28 if (navigator.appName == 'Microsoft Internet Explorer') {
29 var ua = navigator.userAgent;
30 var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
31 if (re.exec(ua) != null)
32 rv = parseFloat(RegExp.$1); // this holds the version number
36 retval = window.open(url, winname, options +
37 ",width=" + width + ",height=" + height +
38 ",left=" + newx + ",top=" + newy +
39 ",screenX=" + newx + ",screenY=" + newy);
44 // recursive window focus-event grabber
45 function grabfocus(w) {
46 for (var i = 0; i < w.frames.length; ++i) grabfocus(w.frames[i]);
47 w.onfocus = top.imfocused;
50 // Call this when a "modal" dialog is desired.
51 // Note that the below function is used for the
52 // frames ui, and that a separate dlgopen function
53 // is used below (see if(top.tab_mode)...) for the tabs ui.
54 function dlgopen(url, winname, width, height) {
55 if (top.modaldialog && !top.modaldialog.closed) {
56 if (window.focus) top.modaldialog.focus();
57 if (top.modaldialog.confirm(top.oemr_dialog_close_msg)) {
58 top.modaldialog.close();
59 top.modaldialog = null;
64 top.modaldialog = cascwin(url, winname, width, height,
65 "resizable=1,scrollbars=1,location=0,toolbar=0");
70 // This is called from del_related() which in turn is invoked by find_code_dynamic.php.
71 // Deletes the specified codetype:code from the indicated input text element.
72 function my_del_related(s, elem, usetitle) {
74 // Deleting everything.
81 // Convert the codes and their descriptions to arrays for easy manipulation.
82 var acodes = elem.value.split(';');
83 var i = acodes.indexOf(s);
85 return; // not found, should not happen
87 // Delete the indicated code and description and convert back to strings.
89 elem.value = acodes.join(';');
91 var atitles = elem.title.split(';');
93 elem.title = atitles.join(';');
99 return Math.floor((1 + Math.random()) * 0x10000)
104 return s4() + s4() + s4() + s4() + s4() + +s4() + s4() + s4();
108 * @summary Responsive dialog modal for tabs interface.
109 * Currently for iframe w/wo header. Still uses opener and window close and resides in top frame.
111 * @param string url iframe Content location.
112 * @param string winname Already opened frame name. (depreciate)
113 * @param number width|modalType For sizing: an int will be converted to a percentage of view port width.
114 * @param number height Ignored for now.
115 * @param boolean forceNewWindow Force using a native window.
116 * @param string title If exist then header with title is created otherwise no header and content only.
120 dlgOpenWindow = dlgopen;
121 dlgopen = function (url, winname, width, height, forceNewWindow, title) {
122 top.restoreSession();
124 if (forceNewWindow) {
125 return dlgOpenWindow(url, winname, width, height);
129 if (url[0] === "/") {
133 fullURL = window.location.href.substr(0, window.location.href.lastIndexOf("/") + 1) + url;
136 /* Depreciate 11/5/17 sjp.
137 var dialogDiv = top.$("#dialogDiv");
139 if (winname !== "_blank") {
140 dlgIframe = dialogDiv.find("iframe[name='" + winname + "']");
143 winname = dialogID();
147 winname = dialogID();
148 var mHeight, mWidth, mSize, msSize, dlgDivContainer;
150 // Convert legacy dialog size to percentages and/or css classes.
151 var sizeChoices = ['modal-sm', 'modal-md', 'modal-mlg', 'modal-lg', 'modal-xl'];
152 if (Number.isInteger(width)) {
153 width = Math.abs(width);
154 mWidth = (width / top.window.innerWidth * 100).toFixed(3) + '%';
155 msSize = '<style>.modal-custom' + winname + ' {width:' + mWidth + ';}</style>';
156 mSize = 'modal-custom' + winname;
157 } else if ($.inArray(width, sizeChoices)) {
158 mSize = width; // is a modal class
160 msSize = 'default'; // standard B.S. modal default (modal-md)
163 if (mSize === 'modal-sm') {
164 msSize = '<style>.modal-sm {width:25%;}</style>';
165 } else if (mSize === 'modal-md') {
166 msSize = '<style>.modal-md {width:50%;}</style>';
167 } else if (mSize === 'modal-mlg') {
168 msSize = '<style>.modal-mlg {width:60%;}</style>';
169 } else if (mSize === 'modal-lg') {
170 msSize = '<style>.modal-lg {width:75%;}</style>';
171 } else if (mSize === 'modal-xlg') {
172 msSize = '<style>.modal-xl {width:96%;}</style>';
175 // Guess at initial responsive height. @TODO Make option for fixed modal size.
176 mHeight = (height / top.window.innerHeight * 100).toFixed(3) + 'vh';
179 var mTitle = title > "" ? '<h4>' + title + '</h4>' : ''; // For now !title = !header and modal full height. Emulates legacy.
182 '<div class="loadProgress text-center">' +
183 '<span class="fa fa-circle-o-notch fa-spin fa-3x text-primary"></span>' +
187 ('<div class="modal-header">%title%</div>')
188 .replace('%title%', mTitle);
191 ('<div id="%id%" class="modal fade dialogModal" tabindex="-1" role="dialog">%sStyle%' +
192 '<div class="modal-dialog %szClass%" role="document">' +
193 '<div class="modal-content">' +
195 '<div class="closeDlgIframe" data-dismiss="modal" ></div>' +
196 '<div class="modal-body" style="height:%initHeight%;">' +
197 '<iframe id="mIframe" class="modalIframe" name="%winname%" frameborder=0 ' +
198 'style="width:100%;height:100%;overflow-y:auto;display:block;" src="%url%">' +
199 '</iframe></div></div></div></div>')
200 .replace('%winname%', winname)
201 .replace('%id%', winname)
202 .replace('%head%', mTitle !== "" ? headerhtml : "")
203 .replace('%url%', fullURL)
204 .replace('%szClass%', mSize)
205 .replace('%initHeight%', mHeight) // May have use later for options.
206 .replace('%sStyle%', msSize !== "default" ? msSize : ''); // default is bootstrap's default.
208 // Write modal html to top window where opener can manage.
209 dlgDivContainer = top.$(mhtml);
210 dlgDivContainer.attr("name", winname);
211 top.$("body").append(dlgDivContainer);
213 // let opener array know about us.
214 top.set_opener(winname, window);
216 // Setup events needed to Calc size, detect window.close, cleanup and auto size modal height on show.
217 $(function () { // DOM Ready.
218 var modalwin = top.$('body').find("[name='" + winname + "']");
219 modalwin.on('load', function (e) {
220 // Larger dialog content may not be completely parsed/rendered even though load event is fired.
221 // Need a little extra time. Adjust here if you encounter auto height default on long frame content.
222 // Not sure why this is but, needed to get accurate content height for auto sizing!!
224 setTimeout(function () {
225 SizeModal(e); // auto size
230 top.$('#' + winname).on('show.bs.modal', function () {
232 $('div.modal-dialog', this).css({'margin': '15px auto'});
233 // leave margins and padding to iframe content style.
234 $('div.modal-body', this).css({
243 top.$('#' + winname).on('shown.bs.modal', function () {
244 // Remove waitHtml spinner/loader etc.
245 $(this).parent().find('div.loadProgress')
246 .fadeOut(function () {
250 // Using jquery-ui plug-in that is loaded in main.php header class.
251 // Cursor styles are in tab sheets.
253 top.$('.modal-content', this).resizable({
254 alsoResize: top.$('div.modal-body', this)
256 top.$('.modal-dialog', this).draggable();
258 top.$('#' + winname).modal('handleUpdate'); // allow for scroll bar
262 // Remove modal html on close. Event is fired from modal close x or window.close()
263 // via include_opener.js where the iframe is destroyed.
265 top.$('#' + winname).on('hidden.bs.modal', function () {
266 console.log('Modal hidden then removed!');
272 top.$('#' + winname).modal({backdrop: 'static', keyboard: true}, 'show');
281 // Do sizing based on view port and frame content length.
282 function SizeModal(e) {
284 var idoc = e.currentTarget.contentDocument ? e.currentTarget.contentDocument : e.currentTarget.contentWindow.document;
285 var frameContentHt = idoc.body.offsetHeight + 60; // add for pad.
286 var viewPortHt = top.window.innerHeight;
287 var size = (frameContentHt / viewPortHt * 100).toFixed(3); // scale to content plus 5% padding.
288 var header = $(e.currentTarget).parent('div.modal-header')[0] ? true : false; // if header missing we need to know.
291 size = 25; // set a min height percentage.
292 } else if (size > 87.5) {
293 if (!header) { // no header so use all view port height that we dare.
297 size = 87.5; // set max height and allow for a header.
301 size = size + 'vh'; // will start the dialog as responsive. Any resize by user turns dialog to absolute positioning.
302 $(e.currentTarget).parent('div.modal-body').css({'padding-right': '10px', 'height': size}); // Set final size. Width was previously set.
304 console.log('Modal loaded and sized! Content:' + frameContentHt + ' Viewport:' + viewPortHt + ' Modal height:' + size);