Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
14 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380
  1. // Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. //
  3. // MIT License (MIT)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a
  6. // copy of this software and associated documentation files (the "Software"),
  7. // to deal in the Software without restriction, including without limitation
  8. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. // and/or sell copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. //
  22. // fields.js
  23. //
  24. // Fields are divided into 2 types
  25. // 1. Standard fields are loaded with the libarary
  26. // 2. Special fields are loaded with form.compressed.js
  27. //
  28. //
  29. // + wrapper
  30. // + input_area
  31. // + display_area
  32. // ======================================================================================
  33. var no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable', 'Button', 'Image'];
  34. var codeid=0; var code_editors={};
  35. function Field() {
  36. this.with_label = 1;
  37. }
  38. Field.prototype.make_body = function() {
  39. var ischk = (this.df.fieldtype=='Check' ? 1 : 0);
  40. // parent element
  41. if(this.parent)
  42. this.wrapper = $a(this.parent, (this.with_label ? 'div' : 'span'));
  43. else
  44. this.wrapper = document.createElement((this.with_label ? 'div' : 'span'));
  45. this.label_area = $a(this.wrapper, 'div', '', {margin:'0px 0px 2px 0px'});
  46. if(ischk && !this.in_grid) {
  47. this.input_area = $a(this.label_area, 'span', '', {marginRight:'4px'});
  48. this.disp_area = $a(this.label_area, 'span', '', {marginRight:'4px'});
  49. }
  50. // label
  51. if(this.with_label) {
  52. this.label_span = $a(this.label_area, 'span', 'small')
  53. // error icon
  54. this.label_icon = $a(this.label_area,'img','',{margin:'-3px 4px -3px 4px'}); $dh(this.label_icon);
  55. this.label_icon.src = 'images/lib/icons/error.gif';
  56. this.label_icon.title = 'Mandatory value needs to be entered';
  57. // error icon
  58. this.suggest_icon = $a(this.label_area,'img','',{margin:'-3px 4px -3px 0px'}); $dh(this.suggest_icon);
  59. this.suggest_icon.src = 'images/lib/icons/bullet_arrow_down.png';
  60. this.suggest_icon.title = 'With suggestions';
  61. } else {
  62. this.label_span = $a(this.label_area, 'span', '', {marginRight:'4px'})
  63. $dh(this.label_area);
  64. }
  65. // make the input areas
  66. if(!this.input_area) {
  67. this.input_area = $a(this.wrapper, (this.with_label ? 'div' : 'span'));
  68. this.disp_area = $a(this.wrapper, (this.with_label ? 'div' : 'span'));
  69. }
  70. // apply style
  71. if(this.in_grid) {
  72. if(this.label_area) $dh(this.label_area);
  73. } else {
  74. this.input_area.className = 'input_area';
  75. $y(this.wrapper,{marginBottom:'9px'});
  76. // set description
  77. this.set_description();
  78. }
  79. // bind label refresh
  80. if(this.onmake)this.onmake();
  81. }
  82. Field.prototype.set_max_width = function() {
  83. var no_max = ['Code', 'Text Editor', 'Text', 'Table', 'HTML']
  84. if(this.wrapper && this.layout_cell && this.layout_cell.parentNode.cells
  85. && this.layout_cell.parentNode.cells.length==1 && !in_list(no_max, this.df.fieldtype)) {
  86. $y(this.wrapper, {paddingRight:'50%'});
  87. }
  88. }
  89. Field.prototype.set_label = function() {
  90. if(this.with_label && this.label_area && this.label!=this.df.label) {
  91. this.label_span.innerHTML = this.df.label;this.label = this.df.label;
  92. }
  93. }
  94. Field.prototype.set_description = function() {
  95. if(this.df.description) {
  96. // parent
  97. var p = in_list(['Text Editor', 'Code', 'Check'], this.df.fieldtype) ? this.label_area : this.wrapper;
  98. this.desc_area = $a(p, 'div', 'help small', '', this.df.description)
  99. // padding on the bottom
  100. if(in_list(['Text Editor', 'Code'], this.df.fieldtype))
  101. $(this.desc_area).addClass('help small');
  102. }
  103. }
  104. // Field Refresh
  105. // --------------------------------------------------------------------------------------------
  106. Field.prototype.get_status = function() {
  107. // if used in filters
  108. if(this.in_filter) this.not_in_form = this.in_filter;
  109. if(this.not_in_form) {
  110. return 'Write';
  111. }
  112. if(!this.df.permlevel) this.df.permlevel = 0;
  113. var p = this.perm[this.df.permlevel];
  114. var ret;
  115. // permission level
  116. if(cur_frm.editable && p && p[WRITE])ret='Write';
  117. else if(p && p[READ])ret='Read';
  118. else ret='None';
  119. // binary
  120. if(this.df.fieldtype=='Binary')
  121. ret = 'None'; // no display for binary
  122. // hidden
  123. if(cint(this.df.hidden))
  124. ret = 'None';
  125. // for submit
  126. if(ret=='Write' && cint(cur_frm.doc.docstatus) > 0) ret = 'Read';
  127. // allow on submit
  128. var a_o_s = cint(this.df.allow_on_submit);
  129. if(a_o_s && (this.in_grid || (this.frm && this.frm.not_in_container))) {
  130. a_o_s = null;
  131. if(this.in_grid) a_o_s = this.grid.field.df.allow_on_submit; // take from grid
  132. if(this.frm && this.frm.not_in_container) { a_o_s = cur_grid.field.df.allow_on_submit;} // take from grid
  133. }
  134. if(cur_frm.editable && a_o_s && cint(cur_frm.doc.docstatus)>0 && !this.df.hidden) {
  135. tmp_perm = get_perm(cur_frm.doctype, cur_frm.docname, 1);
  136. if(tmp_perm[this.df.permlevel] && tmp_perm[this.df.permlevel][WRITE])ret='Write';
  137. }
  138. return ret;
  139. }
  140. Field.prototype.set_style_mandatory = function(add) {
  141. if(add) {
  142. $(this.txt ? this.txt : this.input).addClass('input-mandatory');
  143. if(this.disp_area) $(this.disp_area).addClass('input-mandatory');
  144. } else {
  145. $(this.txt ? this.txt : this.input).removeClass('input-mandatory');
  146. if(this.disp_area) $(this.disp_area).removeClass('input-mandatory');
  147. }
  148. }
  149. Field.prototype.refresh_mandatory = function() {
  150. if(this.in_filter)return;
  151. // mandatory changes
  152. if(this.df.reqd) {
  153. if(this.label_area) this.label_area.style.color= "#d22";
  154. this.set_style_mandatory(1);
  155. } else {
  156. if(this.label_area) this.label_area.style.color= "#222";
  157. this.set_style_mandatory(0);
  158. }
  159. this.refresh_label_icon()
  160. this.set_reqd = this.df.reqd;
  161. }
  162. Field.prototype.refresh_display = function() {
  163. // from permission
  164. if(!this.current_status || this.current_status!=this.disp_status) { // status changed
  165. if(this.disp_status=='Write') { // write
  166. if(this.make_input&&(!this.input)) { // make input if reqd
  167. this.make_input();
  168. if(this.onmake_input) this.onmake_input();
  169. }
  170. if(this.show) this.show()
  171. else { $ds(this.wrapper); }
  172. // input or content
  173. if(this.input) { // if there, show it!
  174. $ds(this.input_area);
  175. $dh(this.disp_area);
  176. if(this.input.refresh)this.input.refresh();
  177. } else { // no widget
  178. $dh(this.input_area);
  179. $ds(this.disp_area);
  180. }
  181. } else if(this.disp_status=='Read') {
  182. // read
  183. if(this.show) this.show()
  184. else { $ds(this.wrapper); }
  185. $dh(this.input_area);
  186. $ds(this.disp_area);
  187. } else {
  188. // None - hide all
  189. if(this.hide) this.hide();
  190. else $dh(this.wrapper);
  191. }
  192. this.current_status = this.disp_status;
  193. }
  194. }
  195. Field.prototype.refresh = function() {
  196. // get status
  197. this.disp_status = this.get_status();
  198. // if there is a special refresh in case of table, then this is not valid
  199. if(this.in_grid
  200. && this.table_refresh
  201. && this.disp_status == 'Write')
  202. { this.table_refresh(); return; }
  203. this.set_label();
  204. this.refresh_display();
  205. // further refresh
  206. if(this.onrefresh)
  207. this.onrefresh(); // called by various fields
  208. if(this.input) {
  209. if(this.input.refresh) this.input.refresh(this.df);
  210. }
  211. if(this.wrapper) {
  212. this.wrapper.fieldobj = this;
  213. $(this.wrapper).trigger('refresh');
  214. }
  215. if(!this.not_in_form)
  216. this.set_input(_f.get_value(this.doctype,this.docname,this.df.fieldname));
  217. this.refresh_mandatory();
  218. this.set_max_width();
  219. }
  220. Field.prototype.refresh_label_icon = function() {
  221. // mandatory
  222. if(this.df.reqd) {
  223. if(this.get_value && is_null(this.get_value())) {
  224. if(this.label_icon) $ds(this.label_icon);
  225. $(this.txt ? this.txt : this.input).addClass('field-to-update')
  226. } else {
  227. if(this.label_icon) $dh(this.label_icon);
  228. $(this.txt ? this.txt : this.input).removeClass('field-to-update')
  229. }
  230. }
  231. }
  232. // Set / display values
  233. // --------------------------------------------------------------------------------------------
  234. Field.prototype.set = function(val) {
  235. // not in form
  236. if(this.not_in_form)
  237. return;
  238. if((!this.docname) && this.grid) {
  239. this.docname = this.grid.add_newrow(); // new row
  240. }
  241. var set_val = val;
  242. if(this.validate)set_val = this.validate(val);
  243. _f.set_value(this.doctype, this.docname, this.df.fieldname, set_val);
  244. this.value = val; // for return
  245. }
  246. Field.prototype.set_input = function(val) {
  247. this.value = val;
  248. if(this.input&&this.input.set_input) {
  249. if(val==null)this.input.set_input('');
  250. else this.input.set_input(val); // in widget
  251. }
  252. var disp_val = val;
  253. if(val==null) disp_val = '';
  254. this.set_disp(disp_val); // text
  255. }
  256. Field.prototype.run_trigger = function() {
  257. // update mandatory icon
  258. this.refresh_label_icon();
  259. if(this.df.reqd && this.get_value && !is_null(this.get_value()) && this.set_as_error)
  260. this.set_as_error(0);
  261. if(this.not_in_form) {
  262. return;
  263. }
  264. if(cur_frm.cscript[this.df.fieldname])
  265. cur_frm.runclientscript(this.df.fieldname, this.doctype, this.docname);
  266. cur_frm.refresh_dependency();
  267. }
  268. Field.prototype.set_disp_html = function(t) {
  269. if(this.disp_area){
  270. $(this.disp_area).addClass('disp_area');
  271. this.disp_area.innerHTML = (t==null ? '' : t);
  272. if(!t) $(this.disp_area).addClass('disp_area_no_val');
  273. }
  274. }
  275. Field.prototype.set_disp = function(val) {
  276. this.set_disp_html(val);
  277. }
  278. Field.prototype.set_as_error = function(set) {
  279. if(this.in_grid || this.in_filter) return;
  280. var w = this.txt ? this.txt : this.input;
  281. if(set) {
  282. $y(w, {border: '2px solid RED'});
  283. } else {
  284. $y(w, {border: '1px solid #888'});
  285. }
  286. }
  287. // Show in GRID
  288. // --------------------------------------------------------------------------------------------
  289. // for grids (activate against a particular record in the table
  290. Field.prototype.activate = function(docname) {
  291. this.docname = docname;
  292. this.refresh();
  293. if(this.input) {
  294. var v = _f.get_value(this.doctype, this.docname, this.df.fieldname);
  295. this.last_value=v;
  296. // set input value
  297. if(this.input.onchange && this.input.get_value && this.input.get_value() !=v) {
  298. if(this.validate)
  299. this.input.set_value(this.validate(v));
  300. else
  301. this.input.set_value((v==null)?'':v);
  302. if(this.format_input)
  303. this.format_input();
  304. }
  305. if(this.input.focus){
  306. try{this.input.focus();} catch(e){} // IE Fix - Unexpected call???
  307. }
  308. }
  309. if(this.txt) {
  310. try{this.txt.focus();} catch(e){} // IE Fix - Unexpected call???
  311. this.txt.field_object = this;
  312. }
  313. }
  314. // ======================================================================================
  315. function DataField() { } DataField.prototype = new Field();
  316. DataField.prototype.make_input = function() {
  317. var me = this;
  318. this.input = $a_input(this.input_area, this.df.fieldtype=='Password' ? 'password' : 'text');
  319. this.get_value= function() {
  320. var v = this.input.value;
  321. if(this.validate)
  322. v = this.validate(v);
  323. return v;
  324. }
  325. this.input.name = this.df.fieldname;
  326. $(this.input).change(function() {
  327. //me.set_value(me.get_value && me.get_value() || $(this.input).val());
  328. // fix: allow 0 as value
  329. me.set_value(me.get_value ? me.get_value() : $(this.input).val());
  330. });
  331. this.set_value = function(val) {
  332. if(!me.last_value)me.last_value='';
  333. if(me.validate) {
  334. val = me.validate(val);
  335. me.input.value = val==undefined ? '' : val;
  336. }
  337. me.set(val);
  338. if(me.format_input)
  339. me.format_input();
  340. if(in_list(['Currency','Float','Int'], me.df.fieldtype)) {
  341. if(flt(me.last_value)==flt(val)) {
  342. me.last_value = val;
  343. return; // do not run trigger
  344. }
  345. }
  346. me.last_value = val;
  347. me.run_trigger();
  348. }
  349. this.input.set_input = function(val) {
  350. if(val==null)val='';
  351. me.input.value = val;
  352. if(me.format_input)me.format_input();
  353. }
  354. // autosuggest type fields
  355. // -----------------------
  356. if(this.df.options=='Suggest') {
  357. // add auto suggest
  358. if(this.suggest_icon) $di(this.suggest_icon);
  359. $(me.input).autocomplete({
  360. source: function(request, response) {
  361. wn.call({
  362. method:'webnotes.widgets.search.search_link',
  363. args: {
  364. 'txt': request.term,
  365. 'dt': me.df.options,
  366. 'query': repl('SELECT DISTINCT `%(fieldname)s` FROM \
  367. `tab%(dt)s` WHERE `%(fieldname)s` LIKE "%s" LIMIT 50',
  368. {fieldname:me.df.fieldname, dt:me.df.parent})
  369. },
  370. callback: function(r) {
  371. response(r.results);
  372. }
  373. });
  374. },
  375. select: function(event, ui) {
  376. me.set(ui.item.value);
  377. }
  378. });
  379. }
  380. }
  381. DataField.prototype.validate = function(v) {
  382. if(this.df.options == 'Phone') {
  383. if(v+''=='')return '';
  384. v1 = ''
  385. // phone may start with + and must only have numbers later, '-' and ' ' are stripped
  386. v = v.replace(/ /g, '').replace(/-/g, '').replace(/\(/g, '').replace(/\)/g, '');
  387. // allow initial +,0,00
  388. if(v && v.substr(0,1)=='+') {
  389. v1 = '+'; v = v.substr(1);
  390. }
  391. if(v && v.substr(0,2)=='00') {
  392. v1 += '00'; v = v.substr(2);
  393. }
  394. if(v && v.substr(0,1)=='0') {
  395. v1 += '0'; v = v.substr(1);
  396. }
  397. v1 += cint(v) + '';
  398. return v1;
  399. } else if(this.df.options == 'Email') {
  400. if(v+''=='')return '';
  401. if(!validate_email(v)) {
  402. msgprint(this.df.label + ': ' + v + ' is not a valid email id');
  403. return '';
  404. } else
  405. return v;
  406. } else {
  407. return v;
  408. }
  409. }
  410. DataField.prototype.onrefresh = function() {
  411. if(this.input&&this.df.colour) {
  412. var col = '#'+this.df.colour.split(':')[1];
  413. $bg(this.input,col);
  414. }
  415. }
  416. // ======================================================================================
  417. function ReadOnlyField() { }
  418. ReadOnlyField.prototype = new Field();
  419. // ======================================================================================
  420. function HTMLField() { }
  421. HTMLField.prototype = new Field();
  422. HTMLField.prototype.with_label = 0;
  423. HTMLField.prototype.set_disp = function(val) { this.disp_area.innerHTML = val; }
  424. HTMLField.prototype.set_input = function(val) { if(val) this.set_disp(val); }
  425. HTMLField.prototype.onrefresh = function() { this.set_disp(this.df.options?this.df.options:''); }
  426. // ======================================================================================
  427. var datepicker_active = 0;
  428. function DateField() { } DateField.prototype = new Field();
  429. DateField.prototype.make_input = function() {
  430. var me = this;
  431. this.user_fmt = wn.control_panel.date_format;
  432. if(!this.user_fmt)this.user_fmt = 'dd-mm-yy';
  433. this.input = $a(this.input_area, 'input');
  434. $(this.input).datepicker({
  435. dateFormat: me.user_fmt.replace('yyyy','yy'),
  436. altFormat:'yy-mm-dd',
  437. changeYear: true,
  438. beforeShow: function(input, inst) {
  439. datepicker_active = 1
  440. },
  441. onClose: function(dateText, inst) {
  442. datepicker_active = 0;
  443. if(_f.cur_grid_cell)
  444. _f.cur_grid_cell.grid.cell_deselect();
  445. }
  446. });
  447. var me = this;
  448. me.input.onchange = function() {
  449. // input as dd-mm-yyyy
  450. if(this.value==null)this.value='';
  451. if(!this.not_in_form)
  452. me.set(dateutil.user_to_str(me.input.value));
  453. me.run_trigger();
  454. }
  455. me.input.set_input = function(val) {
  456. if(val==null)val='';
  457. else val=dateutil.str_to_user(val);
  458. me.input.value = val;
  459. }
  460. me.get_value = function() {
  461. if(me.input.value)
  462. return dateutil.user_to_str(me.input.value);
  463. }
  464. }
  465. DateField.prototype.set_disp = function(val) {
  466. var v = dateutil.str_to_user(val);
  467. if(v==null)v = '';
  468. this.set_disp_html(v);
  469. }
  470. DateField.prototype.validate = function(v) {
  471. if(!v) return;
  472. var me = this;
  473. this.clear = function() {
  474. msgprint ("Date must be in format " + this.user_fmt);
  475. me.input.set_input('');
  476. return '';
  477. }
  478. var t = v.split('-');
  479. if(t.length!=3) { return this.clear(); }
  480. else if(cint(t[1])>12 || cint(t[1])<1) { return this.clear(); }
  481. else if(cint(t[2])>31 || cint(t[2])<1) { return this.clear(); }
  482. return v;
  483. };
  484. // ======================================================================================
  485. // reference when a new record is created via link
  486. function LinkField() { } LinkField.prototype = new Field();
  487. LinkField.prototype.make_input = function() {
  488. var me = this;
  489. if(me.df.no_buttons) {
  490. this.txt = $a(this.input_area, 'input');
  491. this.input = this.txt;
  492. } else {
  493. makeinput_popup(this, 'icon-search', 'icon-play', 'icon-plus');
  494. // setup buttons
  495. me.setup_buttons();
  496. me.onrefresh = function() {
  497. if(me.can_create && cur_frm.doc.docstatus==0)
  498. $(me.btn2).css('display', 'inline-block');
  499. else $dh(me.btn2);
  500. }
  501. }
  502. me.txt.field_object = this;
  503. // set onchange triggers
  504. me.input.set_input = function(val) {
  505. if(val==undefined)val='';
  506. me.txt.value = val;
  507. }
  508. me.get_value = function() { return me.txt.value; }
  509. $(me.txt).autocomplete({
  510. source: function(request, response) {
  511. wn.call({
  512. method:'webnotes.widgets.search.search_link',
  513. args: {
  514. 'txt': request.term,
  515. 'dt': me.df.options,
  516. 'query': me.get_custom_query()
  517. },
  518. callback: function(r) {
  519. response(r.results);
  520. },
  521. });
  522. },
  523. select: function(event, ui) {
  524. me.set_input_value(ui.item.value);
  525. }
  526. }).data('autocomplete')._renderItem = function(ul, item) {
  527. return $('<li></li>')
  528. .data('item.autocomplete', item)
  529. .append(repl('<a>%(label)s<br><span style="font-size:10px">%(info)s</span></a>', item))
  530. .appendTo(ul);
  531. };
  532. $(this.txt).change(function() {
  533. var val = $(this).val();//me.get_value();
  534. me.set_input_value_executed = false;
  535. if(!val) {
  536. if(selector && selector.display)
  537. return;
  538. me.set_input_value('');
  539. } else {
  540. // SetTimeout hack! if in put is set via autocomplete, do not validate twice
  541. setTimeout(function() {
  542. if (!me.set_input_value_executed) {
  543. me.set_input_value(val);
  544. }
  545. }, 1000);
  546. }
  547. })
  548. }
  549. LinkField.prototype.get_custom_query = function() {
  550. this.set_get_query();
  551. if(this.get_query) {
  552. if(cur_frm)
  553. var doc = locals[cur_frm.doctype][cur_frm.docname];
  554. return this.get_query(doc, this.doctype, this.docname);
  555. }
  556. }
  557. LinkField.prototype.setup_buttons = function() {
  558. var me = this;
  559. // magnifier - search
  560. me.btn.onclick = function() {
  561. selector.set(me, me.df.options, me.df.label);
  562. selector.show(me.txt);
  563. }
  564. // open
  565. if(me.btn1)me.btn1.onclick = function() {
  566. if(me.txt.value && me.df.options) { loaddoc(me.df.options, me.txt.value); }
  567. }
  568. // add button - for inline creation of records
  569. me.can_create = 0;
  570. if((!me.not_in_form) && in_list(profile.can_create, me.df.options)) {
  571. me.can_create = 1;
  572. me.btn2.onclick = function() {
  573. var on_save_callback = function(new_rec) {
  574. if(new_rec) {
  575. var d = _f.calling_doc_stack.pop(); // patch for composites
  576. locals[d[0]][d[1]][me.df.fieldname] = new_rec;
  577. me.refresh();
  578. if(me.grid)me.grid.refresh();
  579. // call script
  580. me.run_trigger();
  581. }
  582. }
  583. _f.calling_doc_stack.push([me.doctype, me.docname]);
  584. new_doc(me.df.options, me.on_new, 1, on_save_callback, me.doctype, me.docname, me.frm.not_in_container);
  585. }
  586. } else {
  587. $dh(me.btn2); $y($td(me.tab,0,2), {width:'0px'});
  588. }
  589. }
  590. LinkField.prototype.set_input_value = function(val) {
  591. var me = this;
  592. // SetTimeout hack! if in put is set via autocomplete, do not validate twice
  593. me.set_input_value_executed = true;
  594. var from_selector = false;
  595. if(selector && selector.display) from_selector = true;
  596. // refresh mandatory style
  597. me.refresh_label_icon();
  598. // not in form, do nothing
  599. if(me.not_in_form) {
  600. $(this.txt).val(val);
  601. return;
  602. }
  603. // same value, do nothing
  604. if(cur_frm) {
  605. if(val == locals[me.doctype][me.docname][me.df.fieldname]) {
  606. //me.set(val); // one more time, grid bug?
  607. me.run_trigger(); // wanted - called as refresh?
  608. return;
  609. }
  610. }
  611. // set in locals
  612. me.set(val);
  613. // deselect cell if in grid
  614. if(_f.cur_grid_cell)
  615. _f.cur_grid_cell.grid.cell_deselect();
  616. // run trigger if value is cleared
  617. if(locals[me.doctype][me.docname][me.df.fieldname] && !val) {
  618. me.run_trigger();
  619. return;
  620. }
  621. me.validate_link(val, from_selector);
  622. }
  623. LinkField.prototype.validate_link = function(val, from_selector) {
  624. // validate the value just entered
  625. var me = this;
  626. var fetch = '';
  627. if(cur_frm.fetch_dict[me.df.fieldname])
  628. fetch = cur_frm.fetch_dict[me.df.fieldname].columns.join(', ');
  629. $c('webnotes.widgets.form.utils.validate_link', {
  630. 'value':val,
  631. 'options':me.df.options,
  632. 'fetch': fetch
  633. },
  634. function(r,rt) {
  635. if(r.message=='Ok') {
  636. // set fetch values
  637. if($(me.txt).val()!=val) {
  638. if((me.grid && !from_selector) || (!me.grid)) {
  639. $(me.txt).val(val);
  640. }
  641. }
  642. if(r.fetch_values)
  643. me.set_fetch_values(r.fetch_values);
  644. me.run_trigger();
  645. } else {
  646. var astr = '';
  647. if(in_list(profile.can_create, me.df.options)) astr = repl('<br><br><span class="link_type" onclick="newdoc(\'%(dt)s\')">Click here</span> to create a new %(dtl)s', {dt:me.df.options, dtl:get_doctype_label(me.df.options)})
  648. msgprint(repl('error:<b>%(val)s</b> is not a valid %(dt)s.<br><br>You must first create a new %(dt)s <b>%(val)s</b> and then select its value. To find an existing %(dt)s, click on the magnifying glass next to the field.%(add)s', {val:me.txt.value, dt:get_doctype_label(me.df.options), add:astr}));
  649. me.txt.value = '';
  650. me.set('');
  651. }
  652. }
  653. );
  654. }
  655. LinkField.prototype.set_fetch_values = function(fetch_values) {
  656. var fl = cur_frm.fetch_dict[this.df.fieldname].fields;
  657. var changed_fields = [];
  658. for(var i=0; i< fl.length; i++) {
  659. if(locals[this.doctype][this.docname][fl[i]]!=fetch_values[i]) {
  660. locals[this.doctype][this.docname][fl[i]] = fetch_values[i];
  661. if(!this.grid) {
  662. refresh_field(fl[i]);
  663. // call trigger on the target field
  664. changed_fields.push(fl[i]);
  665. }
  666. }
  667. }
  668. // run triggers
  669. for(i=0; i<changed_fields.length; i++) {
  670. if(cur_frm.fields_dict[changed_fields[i]]) // on main
  671. cur_frm.fields_dict[changed_fields[i]].run_trigger();
  672. }
  673. // refresh grid
  674. if(this.grid) this.grid.refresh();
  675. }
  676. LinkField.prototype.set_get_query = function() {
  677. if(this.get_query)return;
  678. if(this.grid) {
  679. var f = this.grid.get_field(this.df.fieldname);
  680. if(f.get_query) this.get_query = f.get_query;
  681. }
  682. }
  683. LinkField.prototype.set_disp = function(val) {
  684. var t = null;
  685. if(val)t = "<a href=\'javascript:loaddoc(\""+this.df.options+"\", \""+val+"\")\'>"+val+"</a>";
  686. this.set_disp_html(t);
  687. }
  688. // ======================================================================================
  689. function IntField() { } IntField.prototype = new DataField();
  690. IntField.prototype.validate = function(v) {
  691. if(isNaN(parseInt(v)))return null;
  692. return cint(v);
  693. };
  694. IntField.prototype.format_input = function() {
  695. if(this.input.value==null) this.input.value='';
  696. }
  697. // ======================================================================================
  698. function FloatField() { } FloatField.prototype = new DataField();
  699. FloatField.prototype.validate = function(v) {
  700. var v= parseFloat(v);
  701. if(isNaN(v))
  702. return null;
  703. return v;
  704. };
  705. FloatField.prototype.format_input = function() {
  706. if(this.input.value==null) this.input.value='';
  707. }
  708. // ======================================================================================
  709. function CurrencyField() { } CurrencyField.prototype = new DataField();
  710. CurrencyField.prototype.format_input = function() {
  711. var v = fmt_money(this.input.value);
  712. if(this.not_in_form) {
  713. if(!flt(this.input.value)) v = ''; // blank in filter
  714. }
  715. this.input.value = v;
  716. }
  717. CurrencyField.prototype.validate = function(v) {
  718. if(v==null || v=='')
  719. return 0;
  720. return flt(v,2);
  721. }
  722. CurrencyField.prototype.set_disp = function(val) {
  723. var v = fmt_money(val);
  724. this.set_disp_html(v);
  725. }
  726. CurrencyField.prototype.onmake_input = function() {
  727. if(!this.input) return;
  728. this.input.onfocus = function() {
  729. if(flt(this.value)==0)this.select();
  730. }
  731. }
  732. // ======================================================================================
  733. function CheckField() { } CheckField.prototype = new Field();
  734. CheckField.prototype.validate = function(v) {
  735. var v= parseInt(v); if(isNaN(v))return 0;
  736. return v;
  737. };
  738. CheckField.prototype.onmake = function() {
  739. this.checkimg = $a(this.disp_area, 'div');
  740. var img = $a(this.checkimg, 'img');
  741. img.src = 'images/lib/ui/tick.gif';
  742. $dh(this.checkimg);
  743. }
  744. CheckField.prototype.make_input = function() { var me = this;
  745. this.input = $a_input(this.input_area,'checkbox');
  746. $y(this.input, {width:"16px", border:'0px', margin:'2px'}); // no specs for checkbox
  747. $(this.input).click(function() {
  748. me.set(this.checked?1:0);
  749. me.run_trigger();
  750. })
  751. this.input.set_input = function(v) {
  752. v = parseInt(v); if(isNaN(v)) v = 0;
  753. if(v) me.input.checked = true;
  754. else me.input.checked=false;
  755. }
  756. this.get_value= function() {
  757. return this.input.checked?1:0;
  758. }
  759. }
  760. CheckField.prototype.set_disp = function(val) {
  761. if (val){ $ds(this.checkimg); }
  762. else { $dh(this.checkimg); }
  763. }
  764. // ======================================================================================
  765. function TextField() { } TextField.prototype = new Field();
  766. TextField.prototype.set_disp = function(val) {
  767. this.disp_area.innerHTML = replace_newlines(val);
  768. }
  769. TextField.prototype.make_input = function() {
  770. var me = this;
  771. if(this.in_grid)
  772. return; // do nothing, text dialog will take over
  773. this.input = $a(this.input_area, 'textarea');
  774. if(this.df.fieldtype=='Small Text')
  775. this.input.style.height = "80px";
  776. this.input.set_input = function(v) {
  777. me.input.value = v;
  778. }
  779. this.input.onchange = function() {
  780. me.set(me.input.value);
  781. me.run_trigger();
  782. }
  783. this.get_value= function() {
  784. return this.input.value;
  785. }
  786. }
  787. // text dialog
  788. var text_dialog;
  789. function make_text_dialog() {
  790. var d = new Dialog(520,410,'Edit Text');
  791. d.make_body([
  792. ['Text', 'Enter Text'],
  793. ['HTML', 'Description'],
  794. ['Button', 'Update']
  795. ]);
  796. d.widgets['Update'].onclick = function() {
  797. var t = this.dialog;
  798. t.field.set(t.widgets['Enter Text'].value);
  799. t.hide();
  800. }
  801. d.onshow = function() {
  802. this.widgets['Enter Text'].style.height = '300px';
  803. var v = _f.get_value(this.field.doctype,this.field.docname,this.field.df.fieldname);
  804. this.widgets['Enter Text'].value = v==null?'':v;
  805. this.widgets['Enter Text'].focus();
  806. this.widgets['Description'].innerHTML = ''
  807. if(this.field.df.description)
  808. $a(this.widgets['Description'], 'div', 'help small', '', this.field.df.description);
  809. }
  810. d.onhide = function() {
  811. if(_f.cur_grid_cell)
  812. _f.cur_grid_cell.grid.cell_deselect();
  813. }
  814. text_dialog = d;
  815. }
  816. TextField.prototype.table_refresh = function() {
  817. if(!this.text_dialog)
  818. make_text_dialog();
  819. text_dialog.set_title('Enter text for "'+ this.df.label +'"');
  820. text_dialog.field = this;
  821. text_dialog.show();
  822. }
  823. // Select
  824. // ======================================================================================
  825. function SelectField() { } SelectField.prototype = new Field();
  826. SelectField.prototype.make_input = function() {
  827. var me = this;
  828. var opt=[];
  829. if(this.in_filter && (!this.df.single_select)) {
  830. // multiple select
  831. this.input = $a(this.input_area, 'select');
  832. this.input.multiple = true;
  833. this.input.style.height = '4em';
  834. this.input.lab = $a(this.input_area, 'div', {fontSize:'9px',color:'#999'});
  835. this.input.lab.innerHTML = '(Use Ctrl+Click to select multiple or de-select)'
  836. } else {
  837. // Single select
  838. this.input = $a(this.input_area, 'select');
  839. this.input.onchange = function() {
  840. if(me.validate)
  841. me.validate();
  842. me.set(sel_val(this));
  843. me.run_trigger();
  844. }
  845. if(this.df.options == 'attach_files:') {
  846. this.file_attach = true;
  847. }
  848. }
  849. // set as single (to be called from report builder)
  850. this.set_as_single = function() {
  851. var i = this.input;
  852. i.multiple = false;
  853. i.style.height = null;
  854. if(i.lab)$dh(i.lab)
  855. }
  856. // refresh options list
  857. this.refresh_options = function(options) {
  858. if(options)
  859. me.df.options = options;
  860. if(this.file_attach)
  861. this.set_attach_options();
  862. me.options_list = me.df.options?me.df.options.split('\n'):[''];
  863. // add options
  864. empty_select(this.input);
  865. if(me.in_filter && me.options_list[0]!='') {
  866. me.options_list = add_lists([''], me.options_list);
  867. }
  868. add_sel_options(this.input, me.options_list);
  869. }
  870. // refresh options
  871. this.onrefresh = function() {
  872. this.refresh_options();
  873. if(this.not_in_form) {
  874. this.input.value = '';
  875. return;
  876. }
  877. if(_f.get_value)
  878. var v = _f.get_value(this.doctype,this.docname,this.df.fieldname);
  879. else {
  880. if(this.options_list && this.options_list.length)
  881. var v = this.options_list[0];
  882. else
  883. var v = null;
  884. }
  885. this.input.set_input(v);
  886. }
  887. this.input.set_input=function(v) {
  888. if(!v) {
  889. if(!me.input.multiple) {
  890. if(me.docname) { // if called from onload without docname being set on fields
  891. if(me.options_list && me.options_list.length) {
  892. me.set(me.options_list[0]);
  893. me.input.value = me.options_list[0];
  894. } else {
  895. me.input.value = '';
  896. }
  897. }
  898. }
  899. } else {
  900. if(me.options_list) {
  901. if(me.input.multiple) {
  902. for(var i=0; i<me.input.options.length; i++) {
  903. me.input.options[i].selected = 0;
  904. if(me.input.options[i].value && inList(typeof(v)=='string'?v.split(","):v, me.input.options[i].value))
  905. me.input.options[i].selected = 1;
  906. }
  907. } else if(in_list(me.options_list, v)){
  908. me.input.value = v;
  909. }
  910. }
  911. }
  912. }
  913. this.get_value= function() {
  914. if(me.input.multiple) {
  915. var l = [];
  916. for(var i=0;i<me.input.options.length; i++ ) {
  917. if(me.input.options[i].selected)l[l.length] = me.input.options[i].value;
  918. }
  919. return l;
  920. } else {
  921. if(me.input.options) {
  922. var val = sel_val(me.input);
  923. if(!val && !me.input.selectedIndex)
  924. val = me.input.options[0].value;
  925. return val;
  926. }
  927. return me.input.value;
  928. }
  929. }
  930. this.set_attach_options = function() {
  931. if(!cur_frm) return;
  932. var fl = cur_frm.doc.file_list;
  933. if(fl) {
  934. this.df.options = '';
  935. var fl = fl.split('\n');
  936. for(var i in fl) {
  937. this.df.options += '\n' + fl[i].split(',')[1];
  938. }
  939. } else {
  940. this.df.options = ''
  941. }
  942. }
  943. this.refresh();
  944. }
  945. // Time
  946. // ======================================================================================
  947. function TimeField() { } TimeField.prototype = new Field();
  948. TimeField.prototype.get_time = function() {
  949. return time_to_hhmm(sel_val(this.input_hr), sel_val(this.input_mn), sel_val(this.input_am));
  950. }
  951. TimeField.prototype.set_time = function(v) {
  952. //show_alert(ret);
  953. ret = time_to_ampm(v);
  954. this.input_hr.inp.value = ret[0];
  955. this.input_mn.inp.value = ret[1];
  956. this.input_am.inp.value = ret[2];
  957. }
  958. TimeField.prototype.set_style_mandatory = function() { }
  959. TimeField.prototype.set_as_error = function() { }
  960. TimeField.prototype.make_input = function() { var me = this;
  961. this.input = $a(this.input_area, 'div', 'time_field');
  962. var t = make_table(this.input, 1, 3, '200px');
  963. var opt_hr = ['1','2','3','4','5','6','7','8','9','10','11','12'];
  964. var opt_mn = ['00','05','10','15','20','25','30','35','40','45','50','55'];
  965. var opt_am = ['AM','PM'];
  966. this.input_hr = new SelectWidget($td(t,0,0), opt_hr, '50px');
  967. this.input_mn = new SelectWidget($td(t,0,1), opt_mn, '50px');
  968. this.input_am = new SelectWidget($td(t,0,2), opt_am, '50px');
  969. var onchange_fn = function() {
  970. me.set(me.get_time());
  971. me.run_trigger();
  972. }
  973. this.input_hr.inp.onchange = onchange_fn;
  974. this.input_mn.inp.onchange = onchange_fn;
  975. this.input_am.inp.onchange = onchange_fn;
  976. this.onrefresh = function() {
  977. var v = _f.get_value ? _f.get_value(me.doctype,me.docname,me.df.fieldname) : null;
  978. me.set_time(v);
  979. if(!v)
  980. me.set(me.get_time());
  981. }
  982. this.input.set_input=function(v) {
  983. if(v==null)v='';
  984. me.set_time(v);
  985. }
  986. this.get_value = function() {
  987. return this.get_time();
  988. }
  989. this.refresh();
  990. }
  991. TimeField.prototype.set_disp=function(v) {
  992. var t = time_to_ampm(v);
  993. var t = t[0]+':'+t[1]+' '+t[2];
  994. this.set_disp_html(t);
  995. }
  996. // ======================================================================================
  997. // Used by date and link fields
  998. function makeinput_popup(me, iconsrc, iconsrc1, iconsrc2) {
  999. var icon_style = {cursor: 'pointer', width: '16px', verticalAlign:'middle',
  1000. marginBottom:'-3px'};
  1001. me.input = $a(me.input_area, 'div');
  1002. if(!me.not_in_form)
  1003. $y(me.input, {width:'80%'});
  1004. me.input.set_width = function(w) {
  1005. $y(me.input, {width:(w-2)+'px'});
  1006. }
  1007. var tab = $a(me.input, 'table');
  1008. me.tab = tab;
  1009. $y(tab, {width:'100%', borderCollapse:'collapse', tableLayout:'fixed'});
  1010. var c0 = tab.insertRow(0).insertCell(0);
  1011. var c1 = tab.rows[0].insertCell(1);
  1012. $y(c1,{width: '20px'});
  1013. me.txt = $a($a($a(c0, 'div', '', {paddingRight:'8px'}), 'div'), 'input', '', {width:'100%'});
  1014. me.btn = $a(c1, 'i', iconsrc, icon_style)
  1015. if(iconsrc1) // link
  1016. me.btn.setAttribute('title','Search');
  1017. else // date
  1018. me.btn.setAttribute('title','Select Date');
  1019. if(iconsrc1) {
  1020. var c2 = tab.rows[0].insertCell(2);
  1021. $y(c2,{width: '20px'});
  1022. me.btn1 = $a(c2, 'i', iconsrc1, icon_style)
  1023. me.btn1.setAttribute('title','Open Link');
  1024. }
  1025. if(iconsrc2) {
  1026. var c3 = tab.rows[0].insertCell(3);
  1027. $y(c3,{width: '20px'});
  1028. me.btn2 = $a(c3, 'i', iconsrc2, icon_style)
  1029. me.btn2.setAttribute('title','Create New');
  1030. $dh(me.btn2);
  1031. }
  1032. if(me.df.colour)
  1033. me.txt.style.background = '#'+me.df.colour.split(':')[1];
  1034. me.txt.name = me.df.fieldname;
  1035. me.setdisabled = function(tf) { me.txt.disabled = tf; }
  1036. }
  1037. var tmpid = 0;
  1038. // ======================================================================================
  1039. _f.ButtonField = function() { };
  1040. _f.ButtonField.prototype = new Field();
  1041. _f.ButtonField.prototype.with_label = 0;
  1042. _f.ButtonField.prototype.init = function() {
  1043. this.prev_button = null;
  1044. // if previous field is a button, add it to the same div!
  1045. // button-set structure
  1046. // + wrapper (1st button)
  1047. // + input_area
  1048. // + button_area
  1049. // + button_area
  1050. // + button_area
  1051. if(!this.frm) return;
  1052. if(cur_frm &&
  1053. cur_frm.fields[cur_frm.fields.length-1] &&
  1054. cur_frm.fields[cur_frm.fields.length-1].df.fieldtype=='Button') {
  1055. this.make_body = function() {
  1056. this.prev_button = cur_frm.fields[cur_frm.fields.length-1];
  1057. if(!this.prev_button.prev_button) {
  1058. // first button, make the button area
  1059. this.prev_button.button_area = $a(this.prev_button.input_area, 'span');
  1060. }
  1061. this.wrapper = this.prev_button.wrapper;
  1062. this.input_area = this.prev_button.input_area;
  1063. this.disp_area = this.prev_button.disp_area;
  1064. // all buttons in the same input_area
  1065. this.button_area = $a(this.prev_button.input_area, 'span');
  1066. }
  1067. }
  1068. }
  1069. _f.ButtonField.prototype.make_input = function() { var me = this;
  1070. if(!this.prev_button) {
  1071. $y(this.input_area,{marginTop:'4px', marginBottom: '4px'});
  1072. }
  1073. // make a button area for one button
  1074. if(!this.button_area)
  1075. this.button_area = $a(this.input_area, 'span','',{marginRight:'4px'});
  1076. // make the input
  1077. this.input = $btn(this.button_area,
  1078. me.df.label, null,
  1079. {fontWeight:'bold'}, null, 1)
  1080. $(this.input).click(function() {
  1081. if(me.not_in_form) return;
  1082. if(cur_frm.cscript[me.df.fieldname] && (!me.in_filter)) {
  1083. cur_frm.runclientscript(me.df.fieldname, me.doctype, me.docname);
  1084. } else {
  1085. cur_frm.runscript(me.df.options, me);
  1086. }
  1087. });
  1088. }
  1089. _f.ButtonField.prototype.hide = function() {
  1090. $dh(this.button_area);
  1091. };
  1092. _f.ButtonField.prototype.show = function() {
  1093. $ds(this.button_area);
  1094. };
  1095. _f.ButtonField.prototype.set = function(v) { }; // No Setter
  1096. _f.ButtonField.prototype.set_disp = function(val) { } // No Disp on readonly
  1097. // ======================================================================================
  1098. function make_field(docfield, doctype, parent, frm, in_grid, hide_label) { // Factory
  1099. switch(docfield.fieldtype.toLowerCase()) {
  1100. // general fields
  1101. case 'data':var f = new DataField(); break;
  1102. case 'password':var f = new DataField(); break;
  1103. case 'int':var f = new IntField(); break;
  1104. case 'float':var f = new FloatField(); break;
  1105. case 'currency':var f = new CurrencyField(); break;
  1106. case 'read only':var f = new ReadOnlyField(); break;
  1107. case 'link':var f = new LinkField(); break;
  1108. case 'date':var f = new DateField(); break;
  1109. case 'time':var f = new TimeField(); break;
  1110. case 'html':var f = new HTMLField(); break;
  1111. case 'check':var f = new CheckField(); break;
  1112. case 'text':var f = new TextField(); break;
  1113. case 'small text':var f = new TextField(); break;
  1114. case 'select':var f = new SelectField(); break;
  1115. case 'button':var f = new _f.ButtonField(); break;
  1116. // form fields
  1117. case 'code':var f = new _f.CodeField(); break;
  1118. case 'text editor':var f = new _f.CodeField(); break;
  1119. case 'table':var f = new _f.TableField(); break;
  1120. case 'section break':var f= new _f.SectionBreak(); break;
  1121. case 'column break':var f= new _f.ColumnBreak(); break;
  1122. case 'image':var f= new _f.ImageField(); break;
  1123. }
  1124. f.parent = parent;
  1125. f.doctype = doctype;
  1126. f.df = docfield;
  1127. f.perm = frm ? frm.perm : [[1,1,1]];
  1128. if(_f)
  1129. f.col_break_width = _f.cur_col_break_width;
  1130. if(in_grid) {
  1131. f.in_grid = true;
  1132. f.with_label = 0;
  1133. }
  1134. if(hide_label) {
  1135. f.with_label = 0;
  1136. }
  1137. if(frm) {
  1138. f.frm = frm;
  1139. if(parent)
  1140. f.layout_cell = parent.parentNode;
  1141. }
  1142. if(f.init) f.init();
  1143. f.make_body();
  1144. return f;
  1145. }