- /**
- * Расширение типов ячеек dhtmlXGrid
- *
- * © Evgeniy Malyarov http://www.oknosoft.ru 2014-2016
- *
- * Экспортирует конструкторы:
- * * **eXcell_ref** - поля ввода значений ссылочных типов
- * * **eXcell_refc** - комбобокс ссылочных типов (перечисления и короткие справочники)
- *
- * @module wdg_dhtmlx
- * @requires common
- */
-
- // Прототип кустомных ячеек для грида
- var eXcell_proto = new eXcell();
-
- /**
- * Обработчик клавиш {tab}, {enter} и {F4} в поле ввода
- */
- eXcell_proto.input_keydown = function(e, t){
-
- function obj_on_select(v){
- if(t.source.on_select)
- t.source.on_select.call(t.source, v);
- }
-
- if(e.keyCode === 8 || e.keyCode === 46){ // по {del} и {bs} очищаем значение
- t.setValue("");
- t.grid.editStop();
- if(t.source.on_select)
- t.source.on_select.call(t.source, "");
-
- }else if(e.keyCode === 9 || e.keyCode === 13)
- t.grid.editStop(); // по {tab} и {enter} заканчиваем редактирование
-
- else if(e.keyCode === 115)
- t.cell.firstChild.childNodes[1].onclick(e); // по {F4} открываем редактор
-
- else if(e.keyCode === 113){ // по {F2} открываем форму объекта
- if(t.source.tabular_section){
- t.mgr = _md.value_mgr(t.source.row, t.source.col, t.source.row._metadata.fields[t.source.col].type);
- if(t.mgr){
- var tv = t.source.row[t.source.col];
- t.mgr.form_obj(t.source.wnd, {
- o: tv,
- on_select: obj_on_select
- });
- }
-
- }else if(t.fpath.length==1){
- t.mgr = _md.value_mgr(t.source.o._obj, t.fpath[0], t.source.o._metadata.fields[t.fpath[0]].type);
- if(t.mgr){
- var tv = t.source.o[t.fpath[0]];
- t.mgr.form_obj(t.source.wnd, {
- o: tv,
- on_select: obj_on_select
- });
- }
- }
- }
-
- return $p.iface.cancel_bubble(e);
- };
-
- /**
- * Конструктор поля ввода со списком OCombo
- * @param cell
- */
- function eXcell_ocombo(cell){
-
- if (!cell)
- return;
-
- var t = this;
-
- t.cell = cell;
- t.grid = cell.parentNode.grid;
-
- /**
- * устанавливает текст в ячейке. например, this.setCValue("<input type='button' value='"+val+"'>",val);
- */
- t.setValue=function(val){
- t.setCValue(val instanceof DataObj ? val.presentation : (val || ""));
- };
-
- /**
- * получает значение ячейки из табличной части или поля объекта или допполя допобъекта, а не из грида
- */
- t.getValue=function(){
- return t.grid.get_cell_value();
-
- };
-
- /**
- * Обрабатывает событие перехода к следующему полю (окончание редактирования)
- */
- t.shiftNext = function () {
- t.grid.editStop();
- };
-
- /**
- * Cоздаёт элементы управления редактора и назначает им обработчики
- */
- t.edit=function(){
-
- if(t.combo)
- return;
-
- t.val = t.getValue(); //save current value
- t.cell.innerHTML = "";
- t.combo = new OCombo({
- parent: t.cell
- }._mixin(t.grid.get_cell_field()));
- t.combo.getInput().focus();
- };
-
- /**
- * вызывается при отключении редактора
- * @return {boolean} - если "истина", значит объект был изменён
- */
- t.detach=function(){
- if(t.combo){
-
- if(t.combo.getComboText){
- t.setValue(t.combo.getComboText()); // текст в элементе управления
- if(!t.combo.getSelectedValue())
- t.combo.callEvent("onChange");
- var res = !$p.utils.is_equal(t.val, t.getValue());// compares the new and the old values
- t.combo.unload();
- return res;
-
- } else if(t.combo.unload){
- t.combo.unload();
- }
- }
- return true;
- }
- }
- eXcell_ocombo.prototype = eXcell_proto;
- window.eXcell_ocombo = eXcell_ocombo;
-
- /**
- * Конструктор поля ввода значений ссылочных типов для грида
- * @param cell
- */
- window.eXcell_ref = eXcell_ocombo;
-
- /**
- * Конструктор комбобокса кешируемых ссылочных типов для грида
- */
- window.eXcell_refc = eXcell_ocombo;
-
- /**
- * Конструктор поля пароля
- */
- function eXcell_pwd(cell){ //the eXcell name is defined here
-
- var fnedit;
- if (cell){ //the default pattern, just copy it
- this.cell = cell;
- this.grid = cell.parentNode.grid;
- eXcell_ed.call(this); //uses methods of the "ed" type
- fnedit = this.edit;
- this.edit = function(){
- fnedit.call(this);
- this.obj.type="password";
- };
- this.setValue=function(){
- this.setCValue("*********");
- };
- this.getValue=function(){
- return this.grid.get_cell_value();
-
- };
- this.detach=function(){
- if(this.grid.get_cell_field){
- var cf = this.grid.get_cell_field();
- cf.obj[cf.field] = this.obj.value;
- }
- this.setValue();
- fnedit = null;
- return this.val != this.getValue();
- }
- }
- }
- eXcell_pwd.prototype = eXcell_proto;
- window.eXcell_pwd = eXcell_pwd;
-
-
- dhtmlXCalendarObject.prototype._dateToStr = function(val, format) {
- if(val instanceof Date && val.getFullYear() < 1000)
- return "";
- else
- return window.dhx4.date2str(val, format||this._dateFormat, this._dateStrings());
- };
-
- eXcell_dhxCalendar.prototype.edit = function() {
-
- var arPos = this.grid.getPosition(this.cell);
- this.grid._grid_calendarA._show(false, false);
- this.grid._grid_calendarA.setPosition(arPos[0],arPos[1]+this.cell.offsetHeight);
- this.grid._grid_calendarA._last_operation_calendar = false;
-
-
- this.grid.callEvent("onCalendarShow", [this.grid._grid_calendarA, this.cell.parentNode.idd, this.cell._cellIndex]);
- this.cell._cediton = true;
- this.val = this.cell.val;
- if(this.val instanceof Date && this.val.getFullYear() < 1000)
- this.val = new Date();
- this._val = this.cell.innerHTML;
- var t = this.grid._grid_calendarA.draw;
- this.grid._grid_calendarA.draw = function(){};
- this.grid._grid_calendarA.setDateFormat((this.grid._dtmask||"%d.%m.%Y"));
- this.grid._grid_calendarA.setDate(this.val||(new Date()));
- this.grid._grid_calendarA.draw = t;
-
- };
-
- /**
- * fix ajax
- */
- (function(){
-
- function fix_auth(t, method, url, async){
- if(url.indexOf("odata/standard.odata") != -1 || url.indexOf("/hs/rest") != -1){
- var username, password;
- if($p.ajax.authorized){
- username = $p.ajax.username;
- password = $p.aes.Ctr.decrypt($p.ajax.password);
-
- }else{
- if($p.job_prm.guest_name){
- username = $p.job_prm.guest_name;
- password = $p.aes.Ctr.decrypt($p.job_prm.guest_pwd);
-
- }else{
- username = $p.wsql.get_user_param("user_name");
- password = $p.aes.Ctr.decrypt($p.wsql.get_user_param("user_pwd"));
- }
- }
- t.open(method, url, async, username, password);
- t.withCredentials = true;
- t.setRequestHeader("Authorization", "Basic " +
- btoa(unescape(encodeURIComponent(username + ":" + password))));
- }else
- t.open(method, url, async);
- }
-
- dhx4.ajax._call = function(method, url, postData, async, onLoad, longParams, headers) {
-
- var t = (window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
- var isQt = (navigator.userAgent.match(/AppleWebKit/) != null && navigator.userAgent.match(/Qt/) != null && navigator.userAgent.match(/Safari/) != null);
-
- if (async == true) {
- t.onreadystatechange = function() {
- if ((t.readyState == 4) || (isQt == true && t.readyState == 3)) { // what for long response and status 404?
- if (t.status != 200 || t.responseText == "")
- if (!dhx4.callEvent("onAjaxError", [{xmlDoc:t, filePath:url, async:async}])) return;
-
- window.setTimeout(function(){
- if (typeof(onLoad) == "function") {
- onLoad.apply(window, [{xmlDoc:t, filePath:url, async:async}]); // dhtmlx-compat, response.xmlDoc.responseXML/responseText
- }
- if (longParams != null) {
- if (typeof(longParams.postData) != "undefined") {
- dhx4.ajax.postLong(longParams.url, longParams.postData, onLoad);
- } else {
- dhx4.ajax.getLong(longParams.url, onLoad);
- }
- }
- onLoad = null;
- t = null;
- },1);
- }
- }
- }
-
- if (method == "GET") {
- url += this._dhxr(url);
- }
-
- t.open(method, url, async);
-
- // если обращение по rest или irest, добавляем авторизацию
- fix_auth(t, method, url, async);
-
- if (headers != null) {
- for (var key in headers) t.setRequestHeader(key, headers[key]);
- } else if (method == "POST" || method == "PUT" || method == "DELETE") {
- t.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- } else if (method == "GET") {
- postData = null;
- }
-
- t.setRequestHeader("X-Requested-With", "XMLHttpRequest");
-
- t.send(postData);
-
- if (async != true) {
- if ((t.readyState == 4) || (isQt == true && t.readyState == 3)) {
- if (t.status != 200 || t.responseText == "") dhx4.callEvent("onAjaxError", [{xmlDoc:t, filePath:url, async:async}]);
- }
- }
-
- return {xmlDoc:t, filePath:url, async:async}; // dhtmlx-compat, response.xmlDoc.responseXML/responseText
-
- };
-
- dhtmlx.ajax.prototype.send = function(url,params,call){
- var x=this.getXHR();
- if (typeof call == "function")
- call = [call];
- //add extra params to the url
- if (typeof params == "object"){
- var t=[];
- for (var a in params){
- var value = params[a];
- if (value === null || value === dhtmlx.undefined)
- value = "";
- t.push(a+"="+encodeURIComponent(value));// utf-8 escaping
- }
- params=t.join("&");
- }
- if (params && !this.post){
- url=url+(url.indexOf("?")!=-1 ? "&" : "?")+params;
- params=null;
- }
-
- //x.open(this.post?"POST":"GET",url,!this._sync);
- fix_auth(x, this.post?"POST":"GET",url,!this._sync);
-
- if (this.post)
- x.setRequestHeader('Content-type','application/x-www-form-urlencoded');
-
- //async mode, define loading callback
- //if (!this._sync){
- var self=this;
- x.onreadystatechange= function(){
- if (!x.readyState || x.readyState == 4){
- //dhtmlx.log_full_time("data_loading"); //log rendering time
- if (call && self)
- for (var i=0; i < call.length; i++) //there can be multiple callbacks
- if (call[i])
- call[i].call((self.master||self),x.responseText,x.responseXML,x);
- self.master=null;
- call=self=null; //anti-leak
- }
- };
- //}
-
- x.send(params||null);
- return x; //return XHR, which can be used in case of sync. mode
- }
-
- })();
-
- /**
- * Проверяет, видна ли ячейка
- * TODO: учесть слой, модальность и т.д.
- */
- dhtmlXCellObject.prototype.is_visible = function () {
- var rect = this.cell.getBoundingClientRect();
- return rect.right > 0 && rect.bottom > 0;
- };
-
-
- $p.iface.data_to_grid = function (data, attr){
-
- if(this.data_to_grid)
- return this.data_to_grid(data, attr);
-
- function cat_picture_class(r){
- var res;
- if(r.hasOwnProperty("posted")){
- res = r.posted ? "cell_doc_posted" : "cell_doc";
- }else{
- res = r.is_folder ? "cell_ref_folder" : "cell_ref_elm";
- }
-
- if(r._deleted)
- res = res + "_deleted";
- return res ;
- }
-
- function do_format(v){
-
- if(v instanceof Date){
- if(v.getHours() || v.getMinutes())
- return $p.moment(v).format($p.moment._masks.date_time);
- else
- return $p.moment(v).format($p.moment._masks.date);
-
- }else
- return typeof v == "number" ? v : $p.iface.normalize_xml(v || "");
- }
-
- var xml = "<?xml version='1.0' encoding='UTF-8'?><rows total_count='%1' pos='%2' set_parent='%3'>"
- .replace("%1", attr._total_count || data.length).replace("%2", attr.start)
- .replace("%3", attr.set_parent || "" ),
- caption = this.caption_flds(attr);
-
- // при первом обращении к методу добавляем описание колонок
- xml += caption.head;
-
- data.forEach(function(r){
- xml += "<row id=\"" + r.ref + "\"><cell class=\"" + cat_picture_class(r) + "\">" + do_format(r[caption.acols[0].id]) + "</cell>";
- for(var col=1; col < caption.acols.length; col++ )
- xml += "<cell>" + do_format(r[caption.acols[col].id]) + "</cell>";
-
- xml += "</row>";
- });
-
- return xml + "</rows>";
- };
-
- /**
- * Создаёт иерархический объект для построения dhtmlxTreeView
- * @param data
- * @return {*[]}
- */
- $p.iface.data_to_tree = function (data) {
-
- var res = [{id: $p.utils.blank.guid, text: "..."}];
-
- function add_hierarchically(arr, row){
- var curr = {id: row.ref, text: row.presentation, items: []};
- arr.push(curr);
- $p._find_rows(data, {parent: row.ref}, function(r){
- add_hierarchically(curr.items, r);
- });
- if(!curr.items.length)
- delete curr.items;
- }
- $p._find_rows(data, {parent: $p.utils.blank.guid}, function(r){
- add_hierarchically(res, r);
- });
-
- return res;
- };
-
-
-
-