You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

collection.js 32 KiB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. /*
  2. * highlight collection in leftbar
  3. */
  4. window.parent.frames["left"].highlightCollection(currentCollection, currentRecordsCount);
  5. /**
  6. * Pad leading zero to numbers
  7. *
  8. * @param integer number Number to pad
  9. * @param integer count Zero count
  10. * @return string
  11. * @since 1.1.6
  12. */
  13. function r_pad_zero(number, count) {
  14. if (typeof(count) == "undefined") {
  15. count = 2;
  16. }
  17. var n = "" + number;
  18. var l = n.length;
  19. if (l < count) {
  20. for (var i = 0; i < count - l; i ++) {
  21. n = "0" + n;
  22. }
  23. }
  24. return n;
  25. }
  26. /*
  27. * show operation buttons for one row
  28. */
  29. function showOperationButtons(id) {
  30. var row = $("#object_" + id);
  31. row.css("background-color", "#eeefff");
  32. //row.css("border", "2px #ccc solid");
  33. }
  34. //hide operation buttons for one row
  35. function hideOperationButtons(id) {
  36. var row = $("#object_" + id);
  37. row.css("background-color", "#fff");
  38. row.css("border", "0");
  39. }
  40. /** expand text area **/
  41. function expandText(id) {
  42. var text = $("#text_" +id);
  43. if (text.attr("expand") == "true") {
  44. text.css("height", "");
  45. text.css("max-height", 150);
  46. text.attr("expand", "false");
  47. $("#expand_" + id).html("Expand");
  48. }
  49. else {
  50. text.css("height", text[0].scrollHeight);
  51. text.css("max-height", text[0].scrollHeight);
  52. text.attr("expand", "true");
  53. $("#expand_" + id).html("Collapse");
  54. }
  55. }
  56. //change command - findAll, modify, remove
  57. function changeCommand(select) {
  58. //newobj input box
  59. var value = select.value;
  60. if (value == "modify") {
  61. $("#newobjInput").show();
  62. }
  63. else {
  64. $("#newobjInput").hide();
  65. }
  66. //limit input box
  67. if (value == "findAll") {
  68. $("#limitLabel").show();
  69. $("#pageSetLabel").show();
  70. $("#fieldsAndHints").show();
  71. }
  72. else {
  73. $("#limitLabel").hide();
  74. $("#pageSetLabel").hide();
  75. $("#fieldsAndHints").hide();
  76. }
  77. }
  78. //switch html and text
  79. function changeText(id) {
  80. var textDiv = $("#text_" + id);
  81. var fieldDiv = $("#field_" + id);
  82. if (textDiv.is(":visible")) {
  83. textDiv.hide();
  84. fieldDiv.show();
  85. }
  86. else {
  87. textDiv.show();
  88. fieldDiv.hide();
  89. }
  90. }
  91. //explain query
  92. function explainQuery(form) {
  93. var params = $(form).serialize().replace(/\baction=[\w\.]+/, "");
  94. jQuery.ajax({
  95. data: params,
  96. success: function (data, textStatus, request) {
  97. $("#records").html(data);
  98. },
  99. url:explainURL,
  100. type:"POST"
  101. });
  102. }
  103. /** show more menus **/
  104. function showMoreMenus(link) {
  105. var obj = $(link);
  106. setManualPosition(".menu", obj.position().left, obj.position().top + obj.height() + 4);
  107. }
  108. /** show manual links **/
  109. function setManualPosition(className, x, y) {
  110. if ($(className).is(":visible")) {
  111. $(className).hide();
  112. }
  113. else {
  114. var s = '$("' + className + '").show().css("left", ' + x + ' - 2)';
  115. if (y) {
  116. s += '.css("top", ' + y + ')';
  117. }
  118. window.setTimeout(s, 100);
  119. $(className).find("a").click(function () {
  120. hideMenus();
  121. });
  122. }
  123. }
  124. /** hide menus **/
  125. function hideMenus() {
  126. $(".menu").hide();
  127. }
  128. /**
  129. * display query fields
  130. */
  131. function showQueryFields(link) {
  132. var fields = $("#query_fields_list");
  133. fields.show();
  134. fields.css("left", $(link).position().left);
  135. fields.css("top", $(link).position().top + $(link).height() + 3);
  136. }
  137. /**
  138. * close query fields div
  139. */
  140. function closeQueryFields() {
  141. $("#query_fields_list").hide();
  142. $("#query_fields_count").html(countChecked("query_fields[]"));
  143. }
  144. /**
  145. * show query hints div
  146. */
  147. function showQueryHints(link) {
  148. var fields = $("#query_hints_list");
  149. fields.show();
  150. fields.css("left", $(link).position().left);
  151. fields.css("top", $(link).position().top + $(link).height() + 3);
  152. }
  153. /**
  154. * close query hints
  155. */
  156. function closeQueryHints() {
  157. $("#query_hints_list").hide();
  158. $("#query_hints_count").html($(".query_hints:checked").length);
  159. }
  160. /**
  161. * count checked boxes
  162. */
  163. function countChecked(name) {
  164. var boxes = document.getElementsByName(name);
  165. var count = 0;
  166. for (var i = 0; i < boxes.length; i ++) {
  167. if (boxes[i].checked) {
  168. count ++;
  169. }
  170. }
  171. return count;
  172. }
  173. /**
  174. * display operations you can apply to a field
  175. */
  176. function showFieldOperations(link, field) {
  177. var link = $(link);
  178. var menu = $("#field_menu");
  179. setManualPosition("#field_menu", link.position().left, link.position().top + link.height());
  180. var parent = link.parent();
  181. while (!parent.is(".record_row")) {
  182. parent = parent.parent();
  183. }
  184. //should show "Hide" and "Show"
  185. if (field == "_id") {//if we are _id, do nothing
  186. menu.children().hide();
  187. menu.find(".field_op_query").show();
  188. menu.find(".field_op_query span").show();
  189. menu.find(".field_op_indexes").show();
  190. menu.find(".field_op_sort").show();
  191. }
  192. else {
  193. menu.children().show();
  194. var queryFields = $("[name='query_fields[]']");
  195. queryFields.each(function (){
  196. var box = $(this);
  197. if (box.val() == field) {
  198. if (box.is(":checked")) {
  199. menu.find(".field_op_show") .hide();
  200. }
  201. else {
  202. menu.find(".field_op_show") .show();
  203. }
  204. return false;
  205. }
  206. });
  207. menu.find(".field_op_hide_show_seperator").show();
  208. menu.find(".field_op_hide") .show();
  209. }
  210. var links = menu.find("a");
  211. links.attr("record_id", parent.attr("record_id"));
  212. links.attr("field", field);
  213. links.attr("record_index", parent.attr("record_index"));
  214. }
  215. /**
  216. * init menu on field
  217. */
  218. function initFieldMenu() {
  219. //record rows
  220. $(".record_row font").dblclick(function(){
  221. return false;
  222. });
  223. $(".record_row span").dblclick(function(){
  224. return false;
  225. });
  226. $(".record_row span.field").click(function (){
  227. $(".menu_arrow").remove();
  228. $(".record_row span.field").css("background-color", "");
  229. var span = $(this);
  230. span.css("background-color", "#ccc");
  231. span.after("<a href=\"#\" style=\"font-size:11px;\" title=\"Field Operations\" onclick=\"showFieldOperations(this,'" + span.attr("field") + "');return false\" class=\"menu_arrow\">▼</a>");
  232. });
  233. }
  234. /**
  235. * init menu on data
  236. */
  237. function initDataMenu() {
  238. $(".string_var").click(function () {
  239. var font = $(this);
  240. var text = font.text();
  241. var matches;
  242. if (matches = text.match(/^"(\w+:\/\/.+)"$/)) {//URI
  243. font.next("a").remove();
  244. font.after("<a href=\"#\" style=\"font-size:11px;\" title=\"View AS\" onclick=\"showDataMenu(this,'" + escape(matches[1]) + "');return false\" class=\"menu_arrow\">▼</a>");
  245. }
  246. else if (matches = text.match(/^"([\w\._]+@[\w\.-]+)"$/)) {//Mail
  247. font.after("<a href=\"#\" style=\"font-size:11px;\" title=\"View AS\" onclick=\"showDataMenu(this,'" + escape(matches[1]) + "');return false\" class=\"menu_arrow\">▼</a>");
  248. }
  249. });
  250. $(".no_string_var").click(function () {
  251. var font = $(this);
  252. var text = font.text();
  253. if (text.match(/^[\d\.]+$/)) {
  254. font.next("a").remove();
  255. font.after("<a href=\"#\" style=\"font-size:11px;\" title=\"View AS\" onclick=\"showDataMenu(this,'" + escape(text) + "');return false\" class=\"menu_arrow\">▼</a>");
  256. }
  257. });
  258. }
  259. function showDataMenu(link, text) {
  260. var link = $(link);
  261. var text = unescape(text);
  262. var menu = [];
  263. var width = 100;
  264. //File size format
  265. if (text.match(/^[\d\.]+$/)) {
  266. var n = parseFloat(text);
  267. menu.push("ToK: " + (Math.round(n/1024*100)/100) + "K");
  268. menu.push("ToM: " + (Math.round(n/1024/1024*100)/100) + "M");
  269. menu.push("ToG: " + (Math.round(n/1024/1024/1024*100)/100) + "G");
  270. //Date format
  271. if (text.length >= 10) {
  272. var date = new Date();
  273. if (text.length >= 13) {
  274. date.setTime(n * 1);
  275. }
  276. else {
  277. date.setTime(n * 1000);
  278. }
  279. menu.push("ToDate: " + date.getFullYear() + "-" + r_pad_zero(date.getMonth() + 1, 2) + "-" + r_pad_zero(date.getDate(), 2) + " " + r_pad_zero(date.getHours(), 2) + ":" + r_pad_zero(date.getMinutes(), 2) + ":" + r_pad_zero(date.getSeconds(), 2));
  280. width = 200;
  281. }
  282. }
  283. //URI format
  284. if (text.match(/^\w+:\/\/.+$/)) {
  285. menu.push("<a href=\"" + text + "\" target=\"_blank\">Go to URI</a>");
  286. if (text.match(/\.(gif|jpg|png)$/i)) {
  287. menu.push("<br/><a href=\"" + text + "\" target=\"_blank\"><img src=\"" + text + "\" style=\"width:100px\"/></a>");
  288. }
  289. }
  290. //Mail
  291. if (text.match(/^([\w\._]+@[\w\.-]+)$/)) {
  292. menu.push("<a href=\"mailto:" + text + "\" target=\"_blank\">Send Mail</a>");
  293. }
  294. //Show menu
  295. if (menu.length > 0) {
  296. $("#data_menu").remove();
  297. var div = "<div class=\"menu\" id=\"data_menu\">";
  298. for (var i = 0; i < menu.length; i ++) {
  299. div += menu[i] + "<br/>";
  300. }
  301. div += "</div>";
  302. $(document.body).append(div)[0];
  303. var dataMenu = $("#data_menu");
  304. dataMenu.css("left", link.position().left + 10);
  305. dataMenu.css("top", link.position().top);
  306. dataMenu.css("width", width);
  307. dataMenu.css("overflow", "auto");
  308. setTimeout(function () { $("#data_menu").show() }, 100);
  309. }
  310. }
  311. /** init the page **/
  312. $(function () {
  313. $(document).click(function (e) {
  314. hideMenus();
  315. $("#field_menu").hide();
  316. if (e.target.tagName == "DIV" || e.target.tagName == "P") {
  317. closeQueryFields();
  318. closeQueryHints();
  319. }
  320. });
  321. //query form
  322. $(".field_orders").find("input[name='field[]']").autocomplete({
  323. source:currentFields,
  324. delay:100
  325. });
  326. initFieldMenu();
  327. initDataMenu();
  328. });
  329. /*
  330. * refresh one record
  331. */
  332. function refreshRecord(id, index) {
  333. var text = $("#text_" + index);
  334. var field = $("#field_" + index);
  335. text.text("loading ...");
  336. var params = {
  337. "id": id,
  338. "db":currentDb,
  339. "collection":currentCollection,
  340. "format":currentFormat
  341. };
  342. var queryFields = $("input[name='query_fields[]']:checked");
  343. for (var i = 0; i < queryFields.length; i ++) {
  344. params["query_fields[" + i + "]"] = $(queryFields[i]).val();
  345. }
  346. jQuery.ajax({
  347. type: "POST",
  348. url: "index.php?action=collection.record",
  349. data: params,
  350. success: function (resp) {
  351. if (resp.code == 200) {
  352. text.html(resp.html);
  353. field.find("textarea").val(resp.data);
  354. initFieldMenu();
  355. initDataMenu();
  356. }
  357. else {
  358. text.text(resp.message);
  359. }
  360. },
  361. dataType: "json"
  362. });
  363. }
  364. //###############field operations#####################
  365. function switchDataType(div, type) {
  366. div.find("[name='data_type']").val(type);
  367. div.find("select[name='format']").hide();
  368. div.find(".value").hide();
  369. div.find(".bool_value").hide();
  370. div.find(".double_value").hide();
  371. div.find(".integer_value").hide();
  372. div.find(".long_value").hide();
  373. div.find(".mixed_value").hide();
  374. switch(type) {
  375. case "integer":
  376. div.find(".integer_value").show();
  377. break;
  378. case "long":
  379. div.find(".long_value").show();
  380. break;
  381. case "float":
  382. case "double":
  383. div.find(".double_value").show();
  384. break;
  385. case "string":
  386. div.find(".value").show();
  387. break;
  388. case "boolean":
  389. div.find(".bool_value").show();
  390. break;
  391. case "null":
  392. break;
  393. case "mixed":
  394. div.find("select[name='format']").show();
  395. div.find(".mixed_value").show();
  396. break;
  397. }
  398. }
  399. function setValueWithData(div, data) {
  400. var dataType = data.type;
  401. var value = data.value;
  402. switch(dataType) {
  403. case "integer":
  404. div.find("[name='integer_value']").val(value);
  405. break;
  406. case "long":
  407. div.find("[name='long_value']").val(value);
  408. break;
  409. case "float":
  410. case "double":
  411. div.find("[name='double_value']").val(value);
  412. break;
  413. case "string":
  414. div.find("[name='value']").val(value);
  415. break;
  416. case "boolean":
  417. div.find("[name='bool_value']").val(value ? "true" : "false");
  418. break;
  419. case "null":
  420. break;
  421. case "mixed":
  422. div.find("[name='mixed_value']").val(data.represent);
  423. break;
  424. }
  425. }
  426. function switchDataTypes(div) {
  427. var div = $(div);
  428. var dataType = div.find("[name='data_type']");
  429. switchDataType(div, dataType.val());
  430. dataType.change(function (){
  431. switchDataType(div, this.value);
  432. });
  433. }
  434. function escapeRegexp(pattern) {
  435. pattern = pattern.replace(/\./, "\\.");
  436. return pattern;
  437. }
  438. function fieldOpHide(link) {
  439. var link = $(link);
  440. var field = link.attr("field");
  441. var checkedCount = 0;
  442. $("[name='query_fields[]']").each(function (){
  443. var box = $(this);
  444. if (box.is(":checked")) {
  445. checkedCount ++;
  446. }
  447. });
  448. var subFieldPattern = new RegExp("^" + escapeRegexp(field) + "\.");
  449. if (checkedCount == 0) {
  450. $("[name='query_fields[]']").each(function (){
  451. var box = $(this);
  452. if (box.val() != field && !box.val().match(subFieldPattern)) {
  453. box.attr("checked", "checked");
  454. }
  455. });
  456. }
  457. else {
  458. $("[name='query_fields[]']").each(function (){
  459. var box = $(this);
  460. if (box.val() == field || box.val().match(subFieldPattern)) {
  461. box.attr("checked", "");
  462. }
  463. });
  464. }
  465. closeQueryFields();
  466. $("#query_form").submit();
  467. }
  468. function fieldOpShow(link) {
  469. var link = $(link);
  470. var field = link.attr("field");
  471. $("[name='query_fields[]']").each(function (){
  472. var box = $(this);
  473. if (box.val() == field) {
  474. box.attr("checked", "checked");
  475. }
  476. });
  477. closeQueryFields();
  478. $("#query_form").submit();
  479. }
  480. function fieldOpQuery(link) {
  481. var link = $(link);
  482. var id = link.attr("record_id");
  483. var field = link.attr("field");
  484. fieldOpLoad(field, id, function (data) {
  485. var buttons = {};
  486. var div = $("#field_dialog_query");
  487. var dataFormat = data.format;
  488. if (dataFormat == "json") {
  489. div.find("[name='field_criteria']").val('{\n\t"' + field + '": ' + data.represent + '\n}');
  490. }
  491. else {
  492. div.find("[name='field_criteria']").val('array(\n\t"' + field + '" => ' + data.represent + ',\n);');
  493. }
  494. buttons["Query"] = function (){
  495. $("textarea[name='criteria']").val(div.find("[name='field_criteria']").val());
  496. $("#query_form").find("input[name='format']").val(div.find("select[name='format']").val());
  497. $("#query_form").submit();
  498. $(this).dialog("close");
  499. }
  500. buttons["Cancel"] = function() {
  501. $(this).dialog("close");
  502. };
  503. div.dialog({
  504. "modal": true,
  505. "title": "Query on field \"" + field + "\"",
  506. "buttons":buttons,
  507. "width": 420,
  508. "open": function () {
  509. $(".ui-widget-overlay").unbind("click").click(function () {
  510. if ($(this).closest(".ui-dialog").length == 0) {
  511. div.dialog("close");
  512. }
  513. });
  514. }
  515. });
  516. });
  517. }
  518. /**
  519. * create new field
  520. *
  521. * @param string link fire link
  522. * @param string id record id
  523. * @param string field field name
  524. * @param integer recordIndex record index
  525. */
  526. function fieldOpNew(link, id, field, recordIndex) {
  527. if (link) {
  528. var link = $(link);
  529. var id = link.attr("record_id");
  530. var field = link.attr("field");
  531. var recordIndex = link.attr("record_index");
  532. }
  533. var buttons = {};
  534. var div = $("#field_dialog_new");
  535. switchDataTypes(div);
  536. if (typeof(field)!="undefined" && field.length > 0) {
  537. div.find("input[name='newname']").val(field + ".");
  538. }
  539. else {
  540. div.find("input[name='newname']").val("");
  541. }
  542. if (id) {
  543. buttons["Apply"] = function () {
  544. jQuery.ajax({
  545. data: {
  546. "id":id,
  547. "db":currentDb,
  548. "collection":currentCollection,
  549. "newname": div.find("input[name='newname']").val(),
  550. "keep":div.find("input[name='keep']:checked").val(),
  551. "data_type":div.find("[name='data_type']").val(),
  552. "value":div.find("[name='value']").val(),
  553. "integer_value":div.find("[name='integer_value']").val(),
  554. "long_value":div.find("[name='long_value']").val(),
  555. "double_value":div.find("[name='double_value']").val(),
  556. "bool_value":div.find("[name='bool_value']").val(),
  557. "mixed_value":div.find("[name='mixed_value']").val(),
  558. "format": div.find("[name='format']").val()
  559. },
  560. success: function (data, textStatus, request) {
  561. if (data.code != 200) {
  562. alert(data.message);
  563. }
  564. else {
  565. div.dialog("close");
  566. if (typeof(recordIndex) != "undefined") {
  567. refreshRecord(id, recordIndex);
  568. }
  569. else {
  570. window.location.reload();
  571. }
  572. }
  573. },
  574. url:"index.php?action=field.new",
  575. type:"POST",
  576. dataType:"json"
  577. });
  578. };
  579. }
  580. buttons["Apply to all"] = function (){
  581. if (!window.confirm("The changes will be applied to all records")) {
  582. return;
  583. }
  584. jQuery.ajax({
  585. data: {
  586. "id":"",
  587. "db":currentDb,
  588. "collection":currentCollection,
  589. "newname": div.find("input[name='newname']").val(),
  590. "keep":div.find("input[name='keep']:checked").val(),
  591. "data_type":div.find("[name='data_type']").val(),
  592. "value":div.find("[name='value']").val(),
  593. "integer_value":div.find("[name='integer_value']").val(),
  594. "long_value":div.find("[name='long_value']").val(),
  595. "double_value":div.find("[name='double_value']").val(),
  596. "bool_value":div.find("[name='bool_value']").val(),
  597. "mixed_value":div.find("[name='mixed_value']").val(),
  598. "format": div.find("[name='format']").val()
  599. },
  600. success: function (data, textStatus, request) {
  601. if (data.code != 200) {
  602. alert(data.message);
  603. }
  604. else {
  605. div.dialog("close");
  606. window.location.reload();
  607. }
  608. },
  609. url:"index.php?action=field.new",
  610. type:"POST",
  611. dataType:"json"
  612. });
  613. }
  614. buttons["Cancel"] = function() {
  615. $(this).dialog("close");
  616. };
  617. div.dialog({
  618. "modal": true,
  619. "title": "Add new field",
  620. "buttons":buttons,
  621. "width": 450,
  622. "open": function () {
  623. $(".ui-widget-overlay").unbind("click").click(function () {
  624. if ($(this).closest(".ui-dialog").length == 0) {
  625. div.dialog("close");
  626. }
  627. });
  628. }
  629. });
  630. }
  631. /**
  632. * load field data
  633. */
  634. function fieldOpLoad(field, id, func) {
  635. jQuery.ajax({
  636. data: {
  637. "id":id,
  638. "db":currentDb,
  639. "collection":currentCollection,
  640. "field": field
  641. },
  642. success: function (data, textStatus, request) {
  643. if (data.code != 200) {
  644. alert(data.message);
  645. }
  646. else {
  647. func(data);
  648. }
  649. },
  650. url:"index.php?action=field.load",
  651. type:"POST",
  652. dataType:"json"
  653. });
  654. }
  655. /**
  656. * update a field
  657. *
  658. * @param object link menu link
  659. * @param mixed id record id
  660. * @param string field field name
  661. * @param integer recordIndex record index
  662. */
  663. function fieldOpUpdate(link, id, field, recordIndex) {
  664. if (link) {
  665. var link = $(link);
  666. var id = link.attr("record_id");
  667. var field = link.attr("field");
  668. var recordIndex = link.attr("record_index");
  669. }
  670. fieldOpLoad(field, id, function (data) {
  671. var buttons = {};
  672. var div = $("#field_dialog_update");
  673. switchDataTypes(div);
  674. switchDataType(div, data.type);
  675. setValueWithData(div, data);
  676. div.find("input[name='newname']").val(field);
  677. if (id) {
  678. buttons["Apply"] = function () {
  679. jQuery.ajax({
  680. data: {
  681. "id":id,
  682. "db":currentDb,
  683. "collection":currentCollection,
  684. "newname": div.find("input[name='newname']").val(),
  685. "data_type":div.find("[name='data_type']").val(),
  686. "value":div.find("[name='value']").val(),
  687. "integer_value":div.find("[name='integer_value']").val(),
  688. "long_value":div.find("[name='long_value']").val(),
  689. "double_value":div.find("[name='double_value']").val(),
  690. "bool_value":div.find("[name='bool_value']").val(),
  691. "mixed_value":div.find("[name='mixed_value']").val(),
  692. "format": div.find("[name='format']").val()
  693. },
  694. success: function (data, textStatus, request) {
  695. if (data.code != 200) {
  696. alert(data.message);
  697. }
  698. else {
  699. div.dialog("close");
  700. if (typeof(recordIndex) != "undefined") {
  701. refreshRecord(id, recordIndex);
  702. }
  703. else {
  704. window.location.reload();
  705. }
  706. }
  707. },
  708. url:"index.php?action=field.update",
  709. type:"POST",
  710. dataType:"json"
  711. });
  712. };
  713. }
  714. buttons["Apply to all"] = function (){
  715. if (!window.confirm("The changes will be applied to all records")) {
  716. return;
  717. }
  718. jQuery.ajax({
  719. data: {
  720. "id":"",
  721. "db":currentDb,
  722. "collection":currentCollection,
  723. "newname": div.find("input[name='newname']").val(),
  724. "data_type":div.find("[name='data_type']").val(),
  725. "value":div.find("[name='value']").val(),
  726. "integer_value":div.find("[name='integer_value']").val(),
  727. "long_value":div.find("[name='long_value']").val(),
  728. "double_value":div.find("[name='double_value']").val(),
  729. "bool_value":div.find("[name='bool_value']").val(),
  730. "mixed_value":div.find("[name='mixed_value']").val(),
  731. "format": div.find("[name='format']").val()
  732. },
  733. success: function (data, textStatus, request) {
  734. if (data.code != 200) {
  735. alert(data.message);
  736. }
  737. else {
  738. div.dialog("close");
  739. window.location.reload();
  740. }
  741. },
  742. url:"index.php?action=field.update",
  743. type:"POST",
  744. dataType:"json"
  745. });
  746. }
  747. buttons["Cancel"] = function() {
  748. $(this).dialog("close");
  749. };
  750. div.dialog({
  751. "modal": true,
  752. "title": "Modify field \"" + field + "\" value",
  753. "buttons":buttons,
  754. "width": 450,
  755. "open": function () {
  756. $(".ui-widget-overlay").unbind("click").click(function () {
  757. if ($(this).closest(".ui-dialog").length == 0) {
  758. div.dialog("close");
  759. }
  760. });
  761. }
  762. });
  763. });
  764. }
  765. function fieldOpRename(link) {
  766. var link = $(link);
  767. var field = link.attr("field");
  768. var id = link.attr("record_id");
  769. var recordIndex = link.attr("record_index");
  770. $(".dialog_field").html(field);
  771. var div = $("#field_dialog_rename");
  772. var buttons = {};
  773. if (id) {
  774. buttons["Apply"] = function () {
  775. jQuery.ajax({
  776. data: {
  777. "id":id,
  778. "field":field,
  779. "db":currentDb,
  780. "collection":currentCollection,
  781. "newname": div.find("input[name='newname']").val(),
  782. "keep": div.find("input[name='keep']:checked").val()
  783. },
  784. success: function (data, textStatus, request) {
  785. if (data.code != 200) {
  786. alert(data.message);
  787. }
  788. else {
  789. div.dialog("close");
  790. if (typeof(recordIndex) != "undefined") {
  791. refreshRecord(id, recordIndex);
  792. }
  793. else {
  794. window.location.reload();
  795. }
  796. }
  797. },
  798. url:"index.php?action=field.rename",
  799. type:"POST",
  800. dataType:"json"
  801. });
  802. };
  803. }
  804. buttons["Apply to all"] = function (){
  805. if (!window.confirm("The changes will be applied to all records")) {
  806. return;
  807. }
  808. jQuery.ajax({
  809. data: {
  810. "id":"",
  811. "field":field,
  812. "db":currentDb,
  813. "collection":currentCollection,
  814. "newname": div.find("input[name='newname']").val(),
  815. "keep":div.find("input[name='keep']:checked").val()
  816. },
  817. success: function (data, textStatus, request) {
  818. if (data.code != 200) {
  819. alert(data.message);
  820. }
  821. else {
  822. div.dialog("close");
  823. window.location.reload();
  824. }
  825. },
  826. url:"index.php?action=field.rename",
  827. type:"POST",
  828. dataType:"json"
  829. });
  830. }
  831. buttons["Cancel"] = function() {
  832. $(this).dialog("close");
  833. };
  834. div.dialog({
  835. "modal": true,
  836. "title": "Rename field \"" + field + "\"",
  837. "buttons":buttons,
  838. "width": 420,
  839. "open": function () {
  840. $(".ui-widget-overlay").unbind("click").click(function () {
  841. if ($(this).closest(".ui-dialog").length == 0) {
  842. div.dialog("close");
  843. }
  844. });
  845. }
  846. });
  847. }
  848. function fieldOpRemove(link) {
  849. var link = $(link);
  850. var field = link.attr("field");
  851. var id = link.attr("record_id");
  852. var recordIndex = link.attr("record_index");
  853. var div = $("#field_dialog_remove");
  854. $(".dialog_field").html(field);
  855. var buttons = {};
  856. if (id) {
  857. buttons["Apply"] = function () {
  858. jQuery.ajax({
  859. data: { "id":id, "field":field, "db":currentDb, "collection":currentCollection },
  860. success: function (data, textStatus, request) {
  861. div.dialog("close");
  862. if (typeof(recordIndex) != "undefined") {
  863. refreshRecord(id, recordIndex);
  864. }
  865. else {
  866. window.location.reload();
  867. }
  868. },
  869. url:"index.php?action=field.remove",
  870. type:"POST"
  871. });
  872. };
  873. }
  874. buttons["Apply to all"] = function (){
  875. if (!window.confirm("The changes will be applied to all records")) {
  876. return;
  877. }
  878. jQuery.ajax({
  879. data: { "id":"", "field":field, "db":currentDb, "collection":currentCollection },
  880. success: function (data, textStatus, request) {
  881. div.dialog("close");
  882. window.location.reload();
  883. },
  884. url:"index.php?action=field.remove",
  885. type:"POST"
  886. });
  887. }
  888. buttons["Cancel"] = function() {
  889. $(this).dialog("close");
  890. };
  891. div.dialog({
  892. "modal": true,
  893. "title": "Remove field \"" + field + "\"",
  894. "buttons":buttons,
  895. "width": 420,
  896. "open": function () {
  897. $(".ui-widget-overlay").unbind("click").click(function () {
  898. if ($(this).closest(".ui-dialog").length == 0) {
  899. div.dialog("close");
  900. }
  901. });
  902. }
  903. });
  904. }
  905. function fieldOpClear(link) {
  906. var link = $(link);
  907. var field = link.attr("field");
  908. var id = link.attr("record_id");
  909. var recordIndex = link.attr("record_index");
  910. var div = $("#field_dialog_clear");
  911. $(".dialog_field").html(field);
  912. var buttons = {};
  913. if (id) {
  914. buttons["Apply"] = function () {
  915. jQuery.ajax({
  916. data: { "id":id, "field":field, "db":currentDb, "collection":currentCollection },
  917. success: function (data, textStatus, request) {
  918. div.dialog("close");
  919. if (typeof(recordIndex) != "undefined") {
  920. refreshRecord(id, recordIndex);
  921. }
  922. else {
  923. window.location.reload();
  924. }
  925. },
  926. url:"index.php?action=field.clear",
  927. type:"POST"
  928. });
  929. };
  930. }
  931. buttons["Apply to all"] = function (){
  932. if (!window.confirm("The changes will be applied to all records")) {
  933. return;
  934. }
  935. jQuery.ajax({
  936. data: { "id":"", "field":field, "db":currentDb, "collection":currentCollection },
  937. success: function (data, textStatus, request) {
  938. div.dialog("close");
  939. window.location.reload();
  940. },
  941. url:"index.php?action=field.clear",
  942. type:"POST"
  943. });
  944. }
  945. buttons["Cancel"] = function() {
  946. $(this).dialog("close");
  947. };
  948. div.dialog({
  949. "modal": true,
  950. "title": "Clear field \"" + field + "\"",
  951. "buttons":buttons,
  952. "width": 420,
  953. "open": function () {
  954. $(".ui-widget-overlay").unbind("click").click(function () {
  955. if ($(this).closest(".ui-dialog").length == 0) {
  956. div.dialog("close");
  957. }
  958. });
  959. }
  960. });
  961. }
  962. function fieldOpIndexes(link) {
  963. var link = $(link);
  964. var field = link.attr("field");
  965. var div = $("#field_dialog_indexes");
  966. div.find(".dialog_field").html(field);
  967. div.find(".first_field").val(field);
  968. div.find("#fields").html("");
  969. div.find("[name='name']").val(field);
  970. div.find("[name='field[]']").autocomplete({ source: currentFields, delay:100 });
  971. jQuery.ajax({
  972. data: {"field": field, "db":currentDb, "collection":currentCollection },
  973. success: function (data, textStatus, request) {
  974. var indexesBody = div.find(".indexes");
  975. indexesBody.html("");
  976. if (data.indexes.length == 0) {
  977. div.find(".indexes_table").hide();
  978. }
  979. else {
  980. div.find(".indexes_table").show();
  981. for (var i in data.indexes) {
  982. var index = data.indexes[i];
  983. indexesBody.append('<tr bgcolor="#ffffff"><td valign="top">' + index.name + '</td><td valign="top">' + index.key + '</td></tr>');
  984. }
  985. }
  986. var buttons = {};
  987. buttons["Create"] = function () {
  988. //parameters
  989. var params = {};
  990. params["db"] = currentDb;
  991. params["collection"] = currentCollection;
  992. params["name"] = div.find("[name='name']").val();
  993. params["is_unique"] = div.find("[name='is_unique']:checked").val();
  994. params["drop_duplicate"] = div.find("[name='drop_duplicate']:checked").val();
  995. var fields = div.find("[name='field[]']");
  996. for (var i = 0; i < fields.length; i ++) {
  997. params["field[" + i + "]"] = $(fields[i]).val();
  998. }
  999. var orders = div.find("[name='order[]']");
  1000. for (var i = 0; i < orders.length; i ++) {
  1001. params["order[" + i + "]"] = $(orders[i]).val();
  1002. }
  1003. jQuery.ajax({
  1004. url: "index.php?action=field.createIndex",
  1005. type: "POST",
  1006. dataType: "json",
  1007. data: params,
  1008. success: function (resp) {
  1009. if (resp.code != 200) {
  1010. alert(resp.message);
  1011. }
  1012. else {
  1013. setTimeout(function () { fieldOpIndexes(link); }, 300)//reload data
  1014. }
  1015. }
  1016. });
  1017. };
  1018. buttons["Cancel"] = function() {
  1019. $(this).dialog("close");
  1020. };
  1021. div.dialog({
  1022. "modal": true,
  1023. "title": "Indexes on field \"" + field + "\"",
  1024. "buttons":buttons,
  1025. "width": 450,
  1026. "open": function () {
  1027. $(".ui-widget-overlay").unbind("click").click(function () {
  1028. if ($(this).closest(".ui-dialog").length == 0) {
  1029. div.dialog("close");
  1030. }
  1031. });
  1032. }
  1033. });
  1034. },
  1035. url: "index.php?action=field.indexes",
  1036. type: "POST",
  1037. dataType: "json"
  1038. });
  1039. }
  1040. /**
  1041. * show more text
  1042. */
  1043. function fieldOpMore(field, id) {
  1044. fieldOpUpdate(null, id, field)
  1045. }
  1046. /**
  1047. * sort by a field
  1048. */
  1049. function fieldOpSort(link, order) {
  1050. var link = $(link);
  1051. var field = link.attr("field");
  1052. var url = window.location.toString();
  1053. var pieces = url.split("?", 2);
  1054. if (pieces.length == 1) {
  1055. window.location = url + "&field[]=" + field + "&order[]=" + order;
  1056. }
  1057. else {
  1058. var params = pieces[1].split("&");
  1059. var newQuery = "";
  1060. var fieldIndex = 0;
  1061. var orderIndex = 0;
  1062. var theFieldIndex = 0;//field to be operated
  1063. for (var i in params) {
  1064. var param = params[i];
  1065. var kv = param.split("=", 2);
  1066. if (kv.length == 2) {
  1067. if (decodeURI(kv[0]).match(new RegExp("^field\\[\\d*\\]$"))) {
  1068. fieldIndex ++;
  1069. if (kv[1] != field) {
  1070. newQuery += "&field[]=" + kv[1];
  1071. }
  1072. else {
  1073. theFieldIndex = fieldIndex;
  1074. }
  1075. }
  1076. else if (decodeURI(kv[0]).match(new RegExp("^order\\[\\d*\\]$"))) {
  1077. orderIndex ++;
  1078. if (orderIndex != theFieldIndex) {
  1079. newQuery += "&order[]=" + kv[1];
  1080. }
  1081. }
  1082. else {
  1083. newQuery += "&" + param;
  1084. }
  1085. }
  1086. }
  1087. window.location = pieces[0] + "?" + "field[]=" + field + "&order[]=" + order + newQuery;
  1088. }
  1089. }
  1090. function addNewField() {
  1091. $("#fields").append("<p style=\"margin:0;padding:0\"><input type=\"text\" name=\"field[]\"/> <select name=\"order[]\"><option value=\"asc\">ASC</option><option value=\"desc\">DESC</option></select> <input type=\"button\" value=\"+\" onclick=\"addNewField()\"/><input type=\"button\" value=\"-\" onclick=\"removeNewField(this)\"/></p>");
  1092. $("#fields").find("[name='field[]']").autocomplete({ source: currentFields, delay:100 });
  1093. }
  1094. function removeNewField(btn) {
  1095. $(btn).parent().remove();
  1096. }
  1097. function clickUniqueKey(box) {
  1098. if (box.checked) {
  1099. $("#duplicate_tr").show();
  1100. }
  1101. else {
  1102. $("#duplicate_tr").hide();
  1103. }
  1104. }
  1105. /**
  1106. * show query history when log_query feature is on
  1107. */
  1108. function showQueryHistory() {
  1109. var div = $("#field_dialog_history");
  1110. var buttons = {
  1111. /** Clear history **/
  1112. "Clear": function () {
  1113. if (window.confirm("Are you sure to clear all the query history?")) {
  1114. jQuery.ajax({
  1115. "data": { "db":currentDb, "collection":currentCollection },
  1116. "dataType": "json",
  1117. "url": "index.php?action=collection.clearQueryHistory",
  1118. "success": function (data) {
  1119. if (data.code == 200) {
  1120. div.find(".no_history").show();
  1121. div.find(".has_history").hide();
  1122. }
  1123. else {
  1124. alert("Fail to clear query history. Please check directory \"$rockmongo/logs/\" permission.");
  1125. }
  1126. }
  1127. });
  1128. }
  1129. },
  1130. "Close": function () {
  1131. $(this).dialog("close");
  1132. }
  1133. };
  1134. /** Retrieve history **/
  1135. jQuery.ajax({
  1136. "data": { "db":currentDb, "collection":currentCollection },
  1137. "dataType": "html",
  1138. "url": "index.php?action=collection.queryHistory",
  1139. "success": function (data) {
  1140. div.html(data);
  1141. div.dialog({
  1142. "modal": true,
  1143. "title": "Query History",
  1144. "buttons":buttons,
  1145. "width": 450,
  1146. "open": function(event, ui) {
  1147. $("button").blur();
  1148. $(".ui-widget-overlay").unbind("click").click(function () {
  1149. if ($(this).closest(".ui-dialog").length == 0) {
  1150. div.dialog("close");
  1151. }
  1152. });
  1153. }
  1154. });
  1155. }
  1156. });
  1157. }
  1158. /**
  1159. * switch format between json and array
  1160. *
  1161. * @param object input data input element
  1162. * @param object select select element
  1163. */
  1164. function switchDataFormat(input, select) {
  1165. $.ajax({
  1166. "data": { "data": $(input).val(), "format":select.value },
  1167. "url": "index.php?action=collection.switchFormat&db=" + currentDb + "&collection=" + currentCollection,
  1168. "type": "POST",
  1169. "dataType": "json",
  1170. "success": function (resp) {
  1171. $(input).val(resp.data);
  1172. }
  1173. });
  1174. }
  1175. /**
  1176. * Show more document operations
  1177. * @param object button "more" button
  1178. * @param integer index document index
  1179. */
  1180. function showMoreDocMenus(button, index) {
  1181. var obj = $(button);
  1182. var className = ".doc_menu_" + index;
  1183. var x = obj.position().left;
  1184. var y = obj.position().top + obj.height() + 4;
  1185. if ($(className).is(":visible")) {
  1186. $(className).hide();
  1187. }
  1188. else {
  1189. window.setTimeout(function () {
  1190. $(".doc_menu").hide();
  1191. $(className).show();
  1192. $(className).css("left", x);
  1193. $(className).css("top", y)
  1194. }, 100);
  1195. $(className).find("a").click(function () {
  1196. showMoreDocMenus(button, index);
  1197. });
  1198. }
  1199. }
  1200. $(function () {
  1201. $(document).click(function () {
  1202. $(".doc_menu").hide();
  1203. });
  1204. });