您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

1284 行
32 KiB

  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. });