PageRenderTime 67ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/SoftWiki/SoftWiki.js

https://bitbucket.org/aksw/softwikiv10
JavaScript | 2333 lines | 1584 code | 314 blank | 435 comment | 286 complexity | fa80b8ec91a4fe643fc49d0427873422 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * SoftWiki Plugin Javascript Component(s)
  3. * Version: $Id: SoftWiki.js 2768 2010-03-12 17:35:32Z triechert $
  4. */
  5. // pseudo constants
  6. var SWORE_REQUIREMENT = 'http://ns.softwiki.de/req/Requirement';
  7. var SWORE_ABSTRACT_REQUIREMENT = 'http://ns.softwiki.de/req/AbstractRequirement';
  8. var SWORE_MODEL = 'http://ns.softwiki.de/req/';
  9. var SWORE_FILE_PROPERTY = 'http://ns.softwiki.de/req/hasLinkedFile';
  10. // softwiki specific ready statements
  11. $jq(document).ready(function() {
  12. $jq(".replace-inline").livequery("click", function() {
  13. hideHref($jq(this));
  14. backParameter="";
  15. $jq("#backToRequirements > input").each(function(){
  16. backParameter+=$jq(this).val()+'&';
  17. });
  18. if (backParameter.length>0) backParameter=backParameter.substr(0,backParameter.length-1);
  19. replaceWindow(
  20. owUriBase + "softwiki/view/",
  21. "r="+encodeURIComponent($jq(this).attr("about")),
  22. null,
  23. function() { showComments(); })
  24. });
  25. $jq("#quicksearch").livequery("keypress", function(event) { swQuickSearch(event); });
  26. $jq("#swEdit").livequery("click", function(event) { swEdit(event); });
  27. $jq("#swLinkproject").livequery("click", function(event) { swLinkproject(event); });
  28. $jq("#swUnlinkproject").livequery("click", function(event) { swUnlinkproject(event); });
  29. $jq(".swRelationEdit").livequery("click", function(event) { swRelationEdit(event); });
  30. $jq("#swCancel").livequery("click", function(event) { swCancel(event); });
  31. $jq("#swSubmit").livequery("click", function(event) { swSubmit(event); });
  32. $jq("#swDelete").livequery("click", function(event) { swDelete(event); });
  33. $jq("#swAddExistingFile").livequery("click", function(event) { swAddExistingFile(event); });
  34. $jq("#swAddNewFile").livequery("click", function(event) { swAddNewFile(event); });
  35. $jq(".swFile").livequery("click", function(event) { swFile(event); });
  36. $jq("#swSubmitFile").livequery("click", function(event) { swSubmitFile(event); });
  37. $jq(".swFileUnlink").livequery("click",function(event) { swFileUnlink(event); });
  38. $jq("#swFileInput").livequery("change",function(event) {
  39. var label = $jq("#swFileInput").attr("value");
  40. var lastpos = label.search(/([^\/\\]+)$/);
  41. var filename = label.substr(lastpos,label.length);
  42. $jq("#swLabelInput").attr("value",filename);
  43. event.stopPropagation();
  44. });
  45. $jq("#swAddExistingDec").livequery("click", function(event) { swAddExistingDec(event); });
  46. $jq("#swAddNewDec").livequery("click", function(event) { swAddNewDec(event); });
  47. $jq(".swDec").livequery("click", function(event) { swDec(event); });
  48. $jq("#swSubmitDec").livequery("click", function(event) { swSubmitDec(event); });
  49. $jq(".swDecUnlink").livequery("click",function(event) { swDecUnlink(event); });
  50. $jq(".swDecTop").livequery("click",function(event) { swDecTop(event); });
  51. $jq(".swDecDown").livequery("click",function(event) { swDecDown(event); });
  52. $jq(".swDecUnTop").livequery("click",function(event) { swDecUnTop(event); });
  53. $jq(".swDecUnDown").livequery("click",function(event) { swDecUnDown(event); });
  54. $jq(".swDecLink").livequery("click",function(event) { swDecLink(event); });
  55. $jq("#swDecInput").livequery("change",function(event) {
  56. var label = $jq("#swDecInput").attr("value");
  57. var lastpos = label.search(/([^\/\\]+)$/);
  58. var filename = label.substr(lastpos,label.length);
  59. $jq("#swLabelInput").attr("value",filename);
  60. event.stopPropagation();
  61. });
  62. // opendirect links via
  63. // http://localhost/ontowiki/softwiki/open/?requirement=...&m=...
  64. var opendirect = $jq("div#opendirect").text();
  65. if (opendirect != "") {
  66. selectedResource = SWORE_REQUIREMENT;
  67. replaceWindow(
  68. owUriBase + "softwiki/view/",
  69. "r="+encodeURIComponent(opendirect),
  70. null,
  71. function() {
  72. showComments();
  73. // set link to standard url to do full request
  74. $jq("a.requirement-back").attr(
  75. 'href',
  76. owUriBase + "resource/list/?r=" + selectedResource
  77. ).removeAttr('class');
  78. });
  79. }
  80. // BEGIN livequeries for the editing of requirement-relations inside a 2nd window BEGIN
  81. $jq("a.input-reqRelation-ok").livequery("click",function(event) {
  82. var queryString = $jq("div.window form#input-reqRelation").serialize();
  83. var targetwin = $jq("#overlays").next();
  84. $jq("#overlays").removeAttr("style");
  85. targetwin.fadeOut("normal");
  86. $jq.get(owUriBase + "softwiki/relationsservice/",queryString,function(data, textStatus) {
  87. if (data.search(/warning:no operations performed/) > -1) {
  88. // do nothing
  89. } else {
  90. var showRelated = $jq('input.toggleReqRelatedCheckbox').attr('checked');
  91. var showSimilar = $jq('input.toggleReqSimilarCheckbox').attr('checked');
  92. var showAll = $jq('input.toggleReqUnrelatedCheckbox').attr('checked');
  93. showRelations(showRelated,showSimilar,showAll);
  94. }
  95. });
  96. event.stopPropagation();
  97. });
  98. $jq("a.input-reqRelation-cancel").livequery("click",function(event) {
  99. var targetwin = $jq("#overlays").next();
  100. $jq("#overlays").removeAttr("style");
  101. targetwin.fadeOut("normal");
  102. event.stopPropagation();
  103. });
  104. // END livequeries for the editing of requirement-relations inside a 2nd window END
  105. $jq(".wrapme").livequery("click", function(event) { swToggleWrap(event); });
  106. $jq(".wrapme").livequery("mouseover", function(event) { $jq(event.target).css("cursor", "pointer"); });
  107. // show default reqlist / and Add Requirement Button
  108. if(typeof(selectedResource)!= "undefined" && opendirect == "") {
  109. replaceWindow(owUriBase + "softwiki/reqlist/", "all=true&resource=" + getSoftWikiFrickelJson(false));
  110. $jq("#swNew").show();
  111. $jq("#swNew").click( function(event) {
  112. // reload main window and remove all other windows
  113. replaceWindow(owUriBase + "softwiki/view/", "new&resources=" + getSoftWikiFrickelJson(false), $jq("div.section-mainwindows").children("div.window").eq(0), function() {newRequirement=event; });
  114. $jq("div.section-mainwindows").children("div.window").slice(1).remove();
  115. //swEdit(window.event);
  116. });
  117. }
  118. // add comment (depends on requirement form now)
  119. $jq("#softwiki-add-comment").livequery("click", function(event) {
  120. if ($jq("#softwiki-comment").val().length==0) alert("You must not post an empty comment.");
  121. else {
  122. var url = owUriBase + 'service/comments/?' + $jq("form.softwiki-comment").serialize() + "&prefix=softwiki";
  123. $jq.get(url,'',function() {
  124. showComments();
  125. });
  126. }
  127. })
  128. // add valuation
  129. $jq("#softwiki-add-valuation").livequery("click", function(event) {
  130. if ($jq("#valuation").val()==0) alert("You have to choose the number of stars.");
  131. else{
  132. var url = owUriBase + 'service/comments/?' + $jq("form.softwiki-valuation").serialize() + "&prefix=softwiki";
  133. $jq.get(url,'',function() {
  134. showComments();
  135. });
  136. }
  137. })
  138. // edit valuation
  139. $jq("#softwiki-edit-valuation").livequery("click", function() {
  140. $jq(".softwiki-valuation .disabled").removeClass("disabled").addClass("wasDisabled");
  141. $jq(".softwiki-valuation :disabled").removeAttr("disabled");
  142. $jq("#softwiki-cancel-valuation").show();
  143. $jq("#softwiki-submit-edit-valuation").show();
  144. $jq("#softwiki-edit-valuation").hide();
  145. })
  146. // cancel valuation
  147. $jq("#softwiki-cancel-valuation").livequery("click", function() {
  148. $jq(".softwiki-valuation .wasDisabled").addClass("disabled").removeClass("wasDisabled").attr("disabled", "disabled");
  149. $jq(".softwiki-valuation").resetForm();
  150. var oldvalue=$jq("#valuation").attr("oldvalue");
  151. $jq("#valuation").attr("value",$jq("#valuation").attr("oldvalue"));
  152. for (var i=1;i<=5;i++)
  153. if (i<=oldvalue) $jq('#valuationStar'+i).attr('src',$jq('#valuationStar'+i).attr('src').replace('icon_star_empty.jpg','icon_star_full.png'));
  154. else $jq('#valuationStar'+i).attr('src',$jq('#valuationStar'+i).attr('src').replace('icon_star_full.png','icon_star_empty.jpg'));
  155. $jq("#softwiki-cancel-valuation").hide();
  156. $jq("#softwiki-submit-edit-valuation").hide();
  157. $jq("#softwiki-edit-valuation").show();
  158. })
  159. // submit edit valuation
  160. $jq("#softwiki-submit-edit-valuation").livequery("click", function() {
  161. if ($jq("#valuation").val()==0) alert("You have to choose the number of stars.");
  162. else{
  163. var url = owUriBase + 'service/comments/?' + $jq("form.softwiki-valuation").serialize()
  164. + "&edit=" + $jq("#valuation").attr("edit") + "&prefix=softwiki";
  165. replaceWindow(url, '', $jq("div.section-mainwindows").children("div.window").eq(1));
  166. }
  167. })
  168. // add tag-description
  169. $jq("#softwiki-add-tag-description").livequery("click", function() {
  170. if ($jq("#tag-description").val().length==0) alert("You must not post an empty tag description.");
  171. else {
  172. loadTags(true, $jq("form.softwiki-tag").serialize());
  173. }
  174. })
  175. // toggle defined tags
  176. $jq(".toggleDefinedTags").livequery("click", function() {
  177. filterTags();
  178. })
  179. //toggle undefined tags
  180. $jq(".toggleUndefinedTags").livequery("click", function() {
  181. filterTags();
  182. })
  183. $jq('.requirement-back').livequery('click', function() {
  184. // reload main window
  185. if (backParameter.length=="") backParameter="all=true&resources="+getSoftWikiFrickelJson(false);
  186. replaceWindow(owUriBase + "softwiki/reqlist/", backParameter);
  187. // remove all other windows
  188. $jq("div.section-mainwindows").children("div.window").slice(1).remove();
  189. });
  190. // assign search function to tag search field
  191. $jq('input#tag-search-input').livequery('keyup', function() {
  192. // using timeout here because tag search via regexp isn't as fast as (case-sensitive) jq contains function
  193. if (typeof(to) != "undefined") {
  194. window.clearTimeout(tagtimeout);
  195. var tagtimeout = window.setTimeout("filterTags()","750");
  196. } else {
  197. var tagtimeout = window.setTimeout("filterTags()","750");
  198. }
  199. });
  200. // req Relations Checkboxes
  201. $jq('.toggleReqSimilarCheckbox').livequery('click', function(event) {
  202. $jq(event.target).parents('div.window').eq(0).addClass('is-processing');
  203. //alert("related: " + $jq('input.toggleReqRelatedCheckbox').attr('checked'));
  204. var showRelated = $jq('input.toggleReqRelatedCheckbox').attr('checked');
  205. //alert("similar: " + $jq('input.toggleReqSimilarCheckbox').attr('checked'));
  206. var showSimilar = $jq('input.toggleReqSimilarCheckbox').attr('checked');
  207. //alert("all: " + $jq('input.toggleReqUnrelatedCheckbox').attr('checked'));
  208. var showAll = $jq('input.toggleReqUnrelatedCheckbox').attr('checked')
  209. showRelations(showRelated,showSimilar,showAll);
  210. });
  211. $jq('.toggleReqRelatedCheckbox').livequery('click', function(event) {
  212. $jq(event.target).parents('div.window').eq(0).addClass('is-processing');
  213. //alert("related: " + $jq('input.toggleReqRelatedCheckbox').attr('checked'));
  214. var showRelated = $jq('input.toggleReqRelatedCheckbox').attr('checked');
  215. //alert("similar: " + $jq('input.toggleReqSimilarCheckbox').attr('checked'));
  216. var showSimilar = $jq('input.toggleReqSimilarCheckbox').attr('checked');
  217. //alert("all: " + $jq('input.toggleReqUnrelatedCheckbox').attr('checked'));
  218. var showAll = $jq('input.toggleReqUnrelatedCheckbox').attr('checked')
  219. showRelations(showRelated,showSimilar,showAll);
  220. });
  221. $jq('.toggleReqUnrelatedCheckbox').livequery('click', function(event) {
  222. $jq(event.target).parents('div.window').eq(0).addClass('is-processing');
  223. //alert("related: " + $jq('input.toggleReqRelatedCheckbox').attr('checked'));
  224. var showRelated = $jq('input.toggleReqRelatedCheckbox').attr('checked');
  225. //alert("similar: " + $jq('input.toggleReqSimilarCheckbox').attr('checked'));
  226. var showSimilar = $jq('input.toggleReqSimilarCheckbox').attr('checked');
  227. //alert("all: " + $jq('input.toggleReqUnrelatedCheckbox').attr('checked'));
  228. var showAll = $jq('input.toggleReqUnrelatedCheckbox').attr('checked')
  229. showRelations(showRelated,showSimilar,showAll);
  230. });
  231. // pager links handle
  232. $jq('a.pager').livequery('click', function() {
  233. page($jq(this));
  234. });
  235. // auto resize for the req description
  236. //$jq("#rdescription").livequery("keyup", function(event) { swReqDescAutoResize(event); });
  237. $jq("span.removetag").livequery('click', function() { if (!$jq(this).parent().hasClass('disabled')) $jq(this).parent().remove(); });
  238. $jq('#rtagsButton').livequery('click', function(event) { addTagWithButton(event); });
  239. $jq('#rVersionButton').livequery('click', function(event) { changeVersionButton(event); });
  240. $jq('#rtagsNew').livequery('keyup', function(event) { suggestTags(event) });
  241. $jq("#rtagsNew").livequery('keyup', function(event) { addTag(event); });
  242. $jq('#rtagsNew-overlay > ul.tag_suggest > li').livequery('click', function(event) { addTagWithClickOnSuggestion($jq(this)); event.stopPropagation(); });
  243. $jq('html').click(function(event) { $jq('#rtagsNew-overlay').remove() });
  244. //$jq('#rtagsNew').livequery('blur', function() { $jq('#rtagsNew-overlay').remove() });
  245. });
  246. // toggles the wrap of req descriptions
  247. function swToggleWrap (event) {
  248. target = $jq(event.target);
  249. if (target.hasClass("nowrap")) {
  250. target.prev().hide();
  251. target.hide();
  252. target.next().show();
  253. target.next().next().show();
  254. } else {
  255. target.hide();
  256. target.prev().hide();
  257. target.prev().prev().show();
  258. target.prev().prev().prev().show();
  259. }
  260. /* content = target.html();
  261. target.toggleClass("nowrap");
  262. target.after("<div style='white-space:normal;'>"+content+"</div>");
  263. target.remove();
  264. */
  265. // todo: hier weitermachen seebi!
  266. }
  267. // pager
  268. function page(button) {
  269. // load vars (JSON doesn't work :\)
  270. var count = parseInt($jq('input#count').attr('value'));
  271. var limit = parseInt($jq('input#limit').attr('value'));
  272. var offset = parseInt($jq('input#offset').attr('value'));
  273. // TODO nheino ;)
  274. var pageUrl = $jq('input#page-url').attr('value').replace(/[\?&]limit=[\d]+/, '').replace(/[\?&]offset=[\d]+/, '');
  275. // which button was clicked
  276. if (button.hasClass('first-page')) {
  277. offset = 0;
  278. } else if (button.hasClass('previous-page')) {
  279. offset -= limit;
  280. } else if (button.hasClass('next-page')) {
  281. offset += limit;
  282. } else if (button.hasClass('last-page')) {
  283. offset = count - (count % limit);
  284. } else {
  285. var page = parseInt(button.attr('id').replace(/page-/, ''));
  286. offset = page * limit - limit;
  287. }
  288. // construct new url
  289. var newPageUrl = pageUrl + '&limit=' + limit + '&offset=' + offset;
  290. // load new page
  291. var view_win = button.parents('div.content').eq(0);
  292. view_win.addClass('is-processing');
  293. $jq.get(owUriBase + 'softwiki/reqlist/', newPageUrl,
  294. function (data, textStatus) {
  295. // only replace window content (keeps tabs 'activetabconent' and title of window)
  296. view_win.replaceWith($jq(data).children('.content').addClass('activetabcontent'));
  297. }
  298. );
  299. }
  300. // quicksearch in the reqlist
  301. function swQuickSearch (event) {
  302. if (event.which == 13) { // do only search if user pressed enter
  303. var searchString = event.target.value;
  304. // TODO nheino
  305. var pageUrl = $jq('input#page-url').attr('value').replace(/[\?&]search=[a-zA-Z0-9]+/, '');
  306. var newPageUrl = pageUrl + '&search=' + searchString;
  307. // load new page
  308. var view_win = $jq(event.target).parents('div.window').eq(0);
  309. view_win.addClass('is-processing');
  310. $jq.get(owUriBase + 'softwiki/reqlist/', newPageUrl,
  311. function (data, textStatus) {
  312. // only replace window content (keeps tabs 'activetabconent' and title of window)
  313. $jq(data).children('.content').addClass('activetabcontent');
  314. view_win.replaceWith($jq(data));
  315. }
  316. );
  317. }
  318. }
  319. // show similar requirements in the second window
  320. function showSimilars () {
  321. var oFCKeditor = FCKeditorAPI.GetInstance('rdescription');
  322. var queryString = "similar=" + encodeURIComponent($jq("#rtitle").val() + " " + stripTags(oFCKeditor.GetXHTML(false))/*$jq("#rdescription").val()*/);
  323. if ($jq("#requirement").attr("about") == "") {
  324. // do nothing
  325. } else {
  326. queryString += "&r=" + $jq("#requirement").attr("about");
  327. }
  328. if ($jq("div.section-mainwindows").children("div.window").size() == 1) {
  329. $jq("div.section-mainwindows").append("<div class='window'></div>");
  330. }
  331. var targetwin = $jq("div.section-mainwindows").children("div.window").eq(1);
  332. if (targetwin) {
  333. replaceWindow(owUriBase + "softwiki/reqlist/", queryString, targetwin);
  334. }
  335. }
  336. // show comments of requirements in the second window
  337. function showComments (showValuations, showComments) {
  338. if (arguments.length==0){
  339. showValuations=true;
  340. showComments=true;
  341. }
  342. else if (arguments.length==1){
  343. showComments=true;
  344. }
  345. if (typeof($jq("#requirement").attr("about")) != 'undefined') {
  346. var queryString = "list&r=" + encodeURIComponent($jq("#requirement").attr("about"))
  347. + "&val="+showValuations+"&com="+showComments
  348. + "&prefix=softwiki";
  349. if ($jq("div.section-mainwindows").children("div.window").size() == 1) {
  350. $jq("div.section-mainwindows").append("<div class='window'></div>");
  351. }
  352. var targetwin = $jq("div.section-mainwindows").children("div.window").eq(1);
  353. targetwin.addClass('is-processing');
  354. if (targetwin) {
  355. taboptionsString = "tab[0][string]=comments.title&tab[0][link]=javascript:showComments();&" +
  356. "tab[1][string]=sw.reqlist.listrelated&tab[1][link]=javascript:showRelations();&" +
  357. "active=0";
  358. $jq.get(owUriBase + "softwiki/extratab/", taboptionsString, function (data, textStatus) {
  359. replaceWindow(owUriBase + "service/comments/", queryString, targetwin, function() {
  360. $jq("div.section-mainwindows").children("div.window").eq(1).children("h1.title").after(data);
  361. $jq("div.section-mainwindows").children("div.window").eq(1).children("div.content").addClass("activetabcontent");
  362. });
  363. });
  364. }
  365. }
  366. }
  367. // show relations of requirements in the second window
  368. function showRelations (showRelated, showSimilar,showAll) {
  369. try{
  370. var oFCKeditor = FCKeditorAPI.GetInstance('rdescription');
  371. showSimilar = (showSimilar == null) ? false : showSimilar;
  372. showRelated = (showRelated == null) ? true : showRelated;
  373. showAll = (showAll == null) ? false : showAll;
  374. //alert(showRelated + ' # ' + showSimilar + ' # ' + showAll);
  375. if (showSimilar) {
  376. var queryString = "similar="+encodeURIComponent($jq("#rtitle").val()) + "%20"
  377. + encodeURIComponent(stripTags(oFCKeditor.GetXHTML(false))/*$jq("#rdescription").val()*/);
  378. } else {
  379. var queryString = "";
  380. }
  381. if (typeof($jq("#requirement").attr("about")) != 'undefined') {
  382. queryString += "&advancedConfig=true&r=" + encodeURIComponent($jq("#requirement").attr("about"))
  383. + "&all=" + showAll + "&relations=" + showRelated;
  384. if ($jq("div.section-mainwindows").children("div.window").size() == 1) {
  385. $jq("div.section-mainwindows").append("<div class='window'></div>");
  386. }
  387. var targetwin = $jq("div.section-mainwindows").children("div.window").eq(1);
  388. if (targetwin) {
  389. taboptionsString = "tab[0][string]=comments.title&tab[0][link]=javascript:showComments();&" +
  390. "tab[1][string]=sw.reqlist.listrelated&tab[1][link]=javascript:showRelations();&" +
  391. "active=1";
  392. $jq.get(owUriBase + "softwiki/extratab/", taboptionsString, function (data, textStatus) {
  393. replaceWindow(owUriBase + "softwiki/reqlist/", queryString, targetwin, function() {
  394. $jq("div.section-mainwindows").children("div.window").eq(1).children("h1.title").after(data);
  395. $jq("div.section-mainwindows").children("div.window").eq(1).children("div.content").addClass("activetabcontent");
  396. });
  397. });
  398. }
  399. }
  400. } catch(e) {}
  401. }
  402. // the requirement form edit button action
  403. function swEdit (event) {
  404. try{
  405. //get instance of the fckeditor
  406. var oFCKeditor = FCKeditorAPI.GetInstance('rdescription');
  407. //show editable title and description
  408. $jq("#noneditDescription").hide();
  409. $jq("#editDescription").show();
  410. $jq("#requirement").ajaxForm();
  411. // show similars of current content
  412. showSimilars();
  413. $jq("#rtitle").change( function() { showSimilars(); } );
  414. // show delete button not for "new requirements"
  415. if ( typeof( $jq("#requirement").attr('about') ) != 'undefined' && $jq("#requirement").attr('about').length!=0
  416. && !( $jq("#requirement").attr('userUri') != $jq("#requirement").attr('Creator') && $jq("#requirement").attr('userUri') != 'http://localhost/OntoWiki/Config/Admin') ) {
  417. $jq("#swDelete").show();
  418. }
  419. $jq("#swSubmit").show();
  420. $jq("#swCancel").show();
  421. $jq("#swEdit").hide();
  422. $jq("#swLinkproject").hide();
  423. $jq("#swUnlinkproject").hide();
  424. $jq(".disabled").removeClass("disabled").addClass("wasDisabled");
  425. $jq(":disabled").removeAttr("disabled");
  426. // show topic selector
  427. $jq('#rtopic-input').hide();
  428. $jq('#rtopic-select').show();
  429. // disable tag submit button by default (no empty tags)
  430. $jq('#rtagsButton').addClass('disabled').removeClass('wasDisabled');
  431. // store suggestable tags
  432. var url = owUriBase + 'service/tagsuggestion';
  433. jQuery.data($jq('#rtagsNew').get(0), 'suggestTags', new Array());
  434. $jq.getJSON(url, function(data) { jQuery.data($jq('#rtagsNew').get(0), 'suggestTags', data); });
  435. jQuery.data($jq('#rtags').get(0), 'rtagsOrig', $jq('#rtags').children('span'));
  436. event.stopPropagation();
  437. } catch(e){}
  438. }
  439. // the requirement form cancel button action
  440. function swCancel (event) {
  441. //hide editable title and description
  442. $jq("#editDescription").hide();
  443. $jq("#noneditDescription").show();
  444. // rebuild second view
  445. showComments();
  446. // rebuild the original tags
  447. $jq('#rtags').children('span').remove();
  448. $jq('#rtagsButton').after(jQuery.data($jq('#rtags').get(0), 'rtagsOrig'));
  449. $jq("#swDelete").hide();
  450. $jq("#swSubmit").hide();
  451. $jq("#swCancel").hide();
  452. $jq("#swEdit").show();
  453. $jq("#swLinkproject").show();
  454. $jq("#swUnlinkproject").show();
  455. $jq(".wasDisabled").addClass("disabled").removeClass("wasDisabled").attr("disabled", "disabled");
  456. $jq("#requirement").resetForm();
  457. //get instance of the fckeditor
  458. var oFCKeditor = FCKeditorAPI.GetInstance('rdescription');
  459. //restore Content
  460. oFCKeditor.SetHTML(oldFCKcontent);
  461. /*$jq('#rdescription').autoResizeTextArea();*/
  462. event.stopPropagation();
  463. }
  464. // the requirement form submit button action
  465. function swSubmit(event) {
  466. //get instance of the fckeditor
  467. var oFCKeditor = FCKeditorAPI.GetInstance('rdescription');
  468. if ($jq('#rtitle').val() == '' ||
  469. stripTags(oFCKeditor.GetXHTML(false)) == '' ||
  470. $jq('#rtopic-select').attr('value') == '' )
  471. {
  472. alert(allFields);
  473. return;
  474. }
  475. // submit data and reload windows to match default requirement view
  476. var targetwin = $jq("div.section-mainwindows").children("div.window").eq(1);
  477. var reqFormElem = $jq("#requirement");
  478. // Tags serialisieren (als JSON)
  479. var tagsJson = '[';
  480. var tags = $jq('#rtags').children('span');
  481. for (var i=0; i<tags.length; ++i) {
  482. tagsJson += '"' + tags.children('span.tag').eq(i).text() + '"';
  483. if (i < (tags.length-1)) {
  484. tagsJson += ','
  485. }
  486. }
  487. tagsJson += ']';
  488. // Buttons und Eingaben deaktivieren
  489. $jq("#swSubmit").hide();
  490. $jq("#swCancel").hide();
  491. $jq("#swDelete").hide();
  492. $jq("#swEdit").hide();
  493. $jq("#swLinkproject").hide();
  494. $jq("#swUnlinkproject").hide();
  495. $jq(".wasDisabled").addClass("disabled").removeClass("wasDisabled").attr("disabled", "disabled");
  496. // Hauptfenster auf is-processing stellen
  497. $jq("div.section-mainwindows div.window div.content").addClass("is-processing");
  498. // query string bauen
  499. var queryString = 'rtitle=' + encodeURIComponent($jq('#rtitle').attr('value')) + '&' +
  500. 'rdescription=' + encodeURIComponent(stripGreenTags(oFCKeditor.GetXHTML( false )).replace(/&nbsp;/g,' ')/*$jq('#rdescription').val()*/) + '&' +
  501. 'rtopic=' + encodeURIComponent($jq('#rtopic-select').attr('value')) + '&' +
  502. 'rtags=' + encodeURIComponent(tagsJson) + '&' +
  503. 'r=' + $jq("#requirement").attr("about");
  504. $jq.get(owUriBase + "softwiki/update/", queryString , function(data, textStatus) {
  505. if ($jq("#requirement").attr("about") == "") {
  506. var response = data.split(":");
  507. $jq("#requirement").attr("about",decodeURIComponent(response[1]));
  508. }
  509. var queryString = "r=" + $jq("#requirement").attr("about");
  510. // reload resource in first window
  511. var targetwin = $jq("div.section-mainwindows").children("div.window").eq(0);
  512. if (targetwin) {
  513. replaceWindow(owUriBase + "softwiki/view/", queryString, targetwin,function() {
  514. });
  515. }
  516. // Show default view (comments)
  517. showComments();
  518. // reload tags
  519. loadTags();
  520. // reload hierarchy
  521. $jq('div.hierarchy').livequery(function() {
  522. var id = $jq(this).attr('id');
  523. loadHierarchy(id, $jq('#' + id).find('ol').eq(0));
  524. });
  525. });
  526. event.stopPropagation();
  527. }
  528. // Delete Requirement
  529. function swDelete(event) {
  530. $jq("div.section-mainwindows").children("div.window").eq(0).toggleClass("is-processing");
  531. $jq("div.section-mainwindows").children("div.window").eq(1).remove();
  532. var queryString = "r=" + $jq("#requirement").attr("about");
  533. $jq.get(owUriBase + "resource/delete", queryString, function (data, textStatus) {
  534. location.reload();
  535. });
  536. }
  537. // link Requirement
  538. function swLinkproject(event) {
  539. try{
  540. $jq("#swLinkproject").hide();
  541. $jq("#swUnlinkproject").show();
  542. var queryString = "r=" + $jq("#requirement").attr("about");
  543. $jq.get(owUriBase + "softwiki/linkproject/", queryString, function (data, textStatus) { });
  544. } catch(e){}
  545. }
  546. // unlink Requirement
  547. function swUnlinkproject(event) {
  548. try{
  549. $jq("#swLinkproject").show();
  550. $jq("#swUnlinkproject").hide();
  551. var queryString = "r=" + $jq("#requirement").attr("about");
  552. $jq.get(owUriBase + "softwiki/unlinkproject/", queryString, function (data, textStatus) { });
  553. } catch(e){}
  554. }
  555. function go(select) {
  556. var wert = select.options[select.options.selectedIndex].value;
  557. if ( wert != "Select") {
  558. window.location.href = wert;
  559. }
  560. }
  561. /* ------------------------- Tags ---------------------------- */
  562. // tagbox-specific load actions
  563. var selectedTags = new Array();
  564. var tempTags = new Array();
  565. // load tags from service
  566. function loadTags(renewTags,queryParameters) {
  567. $jq('.window#tags').livequery(function() {
  568. if (renewTags) {
  569. selectedTags = new Array();
  570. }
  571. var url = owUriBase + 'service/tags/';//'?tags=' + getSoftWikiFrickelJson(true);
  572. if (queryParameters)
  573. queryParameters+='&tags='+getSoftWikiFrickelJson(true);
  574. else
  575. queryParameters='tags='+getSoftWikiFrickelJson(true);
  576. if (selectedResource) {
  577. url += '?r=' + selectedResource;
  578. if (queryParameters){
  579. url += '&' + queryParameters;
  580. }
  581. }
  582. else if (queryParameters){
  583. url += '?' + queryParameters;
  584. }
  585. $jq.ajax({
  586. url: url,
  587. dataType: 'html',
  588. data: tagParams,
  589. success: function(content) {
  590. $jq('.window#tags').contents('.content').children('ol').remove();
  591. $jq('.window#tags').contents('.content').children('div').remove();
  592. $jq('.window#tags').contents('.content').append(content);
  593. tempTags = selectedTags;
  594. selectedTags = new Array();
  595. }
  596. });
  597. });
  598. }
  599. $jq(document).ready(function() {
  600. // load json params from dom tree
  601. eval($jq('.window#tags').find('script').html());
  602. $jq('#tag-search-input').livequery(function() {
  603. $jq.each($jq('#tag-search-input'), function(id, input) {
  604. enhanceInput(input);
  605. })
  606. $jq('#tag-search-input').clearTagSearchInput();
  607. });
  608. $jq('.tag.javascript-on').livequery(function() {
  609. if (tempTags && jQuery.inArray($jq(this).attr('about'), tempTags) > -1) {
  610. $jq(this).addClass('selected');
  611. selectedTags.push($jq(this).attr('about'));
  612. }
  613. });
  614. $jq('.tag.javascript-on').livequery('click', function() {
  615. var tagA = $jq(this);
  616. var tagUri = tagA.attr('about');
  617. // insert clicked tag into tags array if it isn't
  618. // already there, else remove it
  619. var pos = jQuery.inArray(tagUri, selectedTags);
  620. if (pos > -1) {
  621. tags = selectedTags.splice(pos, 1);
  622. } else {
  623. selectedTags.push(tagUri);
  624. }
  625. // toggle tag selection
  626. tagA.toggleClass('selected');
  627. // reload main window
  628. // selectedTags = new Array();
  629. replaceWindow(owUriBase + "softwiki/reqlist/", "all=true&resources=" + getSoftWikiFrickelJson(false));
  630. $jq("div.section-mainwindows").children("div.window").slice(1).remove();
  631. loadTags(false,'tagUri='+tagUri);
  632. // alert('Reloading page: ' + owUriBase + 'softwiki/reqlist/...');
  633. });
  634. });
  635. /* ---------------------- Hierarchy -------------------------- */
  636. // hierarchy-specific load actions
  637. $jq(document).ready(function() {
  638. loadTags();
  639. // load hierarchy for each hierarchy box
  640. $jq('div.hierarchy').livequery(function() {
  641. var id = $jq(this).attr('id');
  642. loadHierarchy(id, $jq('#' + id).find('ol').eq(0));
  643. if (selectedResource == 'http://ns.softwiki.de/req/Requirement') {
  644. $jq('.resource-select.root').addClass('selected');
  645. }
  646. });
  647. // assign search function to hierarchy search field
  648. $jq('input.hierarchy-search-input').livequery('keyup', function() {
  649. filterHierarchy($jq(this).attr('id').replace('-search-input', ''));
  650. });
  651. $jq('.tree-node-toggle').livequery('click', function() {
  652. toggleTree($jq(this).attr('id'));
  653. });
  654. $jq('.tree-open').livequery(function() {
  655. if (!$jq(this).nextAll('ol').children().length) {
  656. var rootId = $jq(this).parents('div.window').attr('id');
  657. var targetOl = $jq(this).nextAll('ol');
  658. var entryUri = $jq(this).next('a').attr('about');
  659. targetOl.show();
  660. loadHierarchy(rootId, targetOl, entryUri);
  661. }
  662. });
  663. $jq('.resource-select').livequery('click', function() {
  664. // store new resource
  665. /*if (selectedResource == $jq(this).attr('about')) {
  666. selectedResource = 'http://ns.softwiki.de/req/Requirement';
  667. $jq('.resource-select.root').addClass('selected');
  668. $jq(this).removeClass('selected');
  669. } else {*/
  670. selectedResource = $jq(this).attr('about');
  671. $jq(".resource-select[@about="+$jq(this).attr('about')+"]").addClass('selected');
  672. //}
  673. // clear tags
  674. selectedTags = new Array();
  675. // update tags
  676. loadTags();
  677. // deselect all others
  678. $jq('.resource-select').each(function(i) {
  679. if ($jq(this).attr('about') != selectedResource) {
  680. $jq(this).removeClass('selected');
  681. }
  682. })
  683. // remove topic selector and container
  684. $jq('#rtopic-select-overlay').remove();
  685. $jq('#rtopic-tree-container').remove();
  686. // reload main window
  687. replaceWindow(owUriBase + "softwiki/reqlist/", "all=true&resources=" + getSoftWikiFrickelJson(false));
  688. // remove all other windows
  689. $jq("div.section-mainwindows").children("div.window").slice(1).remove();
  690. // alert('Reloading page: ' + owUriBase + 'softwiki/reqlist/...');
  691. selectedTags = new Array();
  692. });
  693. });
  694. function toggleTree(id) {
  695. var elem = $jq('#' + id);
  696. var entryUri = elem.next('a').attr('about');
  697. if (elem.is('.tree-open')) {
  698. elem.removeClass('tree-open').addClass('tree-closed');
  699. elem.nextAll('ol').slideUp('fast', function() {
  700. elem.nextAll('ol').children().remove();
  701. });
  702. // save node state in session
  703. setSessionVar('name=nodeState&nodeState[' + encodeURIComponent(entryUri) + ']=closed');
  704. } else {
  705. elem.removeClass('tree-closed').addClass('tree-open');
  706. // save node state in session
  707. setSessionVar('name=nodeState&nodeState[' + encodeURIComponent(entryUri) + ']=open');
  708. }
  709. }
  710. function loadHierarchy(id, target, entryUri) {
  711. target.addClass('is-processing');
  712. $jq('.resource-select.root').show();
  713. // load json params from dom tree
  714. eval($jq('#' + id).find('script').text());
  715. var url = owUriBase + 'service/gettreenodecontent/';
  716. if (typeof(entryUri) != 'undefined') {
  717. // url += '?r=' + encodeURIComponent(entryUri);
  718. hierarchyParams.r = entryUri;
  719. }
  720. if ($jq('#' + id).hasClass('javascript-on')) {
  721. hierarchyParams.javascript = true;
  722. }
  723. $jq.ajax({
  724. url: url,
  725. dataType: 'html',
  726. data: hierarchyParams,
  727. success: function(content) {
  728. if (target.children().length) {
  729. target.children().fadeOut(effectTime, function() {
  730. target.children().remove();
  731. target.prepend(content);
  732. target.removeClass('is-processing');
  733. });
  734. } else {
  735. target.prepend(content);
  736. target.removeClass('is-processing');
  737. }
  738. }
  739. });
  740. }
  741. // store the text length for the next round
  742. var lastLength = 0;
  743. var count = 0;
  744. function filterHierarchy(id) {
  745. var text = jQuery.trim($jq('#' + id + '-search-input').val());
  746. var localCount = ++count;
  747. // load json params from dom tree
  748. eval($jq('#' + id).find('script').text());
  749. window.setTimeout(function() {
  750. // count has not been changed by another call, i.e. no more text entered
  751. if (count == localCount) {
  752. if ((text.length >= autoCompleteMinChars)) {
  753. // enable javascript-only links
  754. if ($jq('#' + id).hasClass('javascript-on')) {
  755. hierarchyParams.javascript = true;
  756. }
  757. $jq('.resource-select.root').hide();
  758. var input = $jq('#' + id + '-search-input');
  759. var target = input.parents('.window').find('ol').eq(0);
  760. target.addClass('is-processing');
  761. $jq.ajax({
  762. url: owUriBase + 'service/gettreenodecontent/?s=' + text,
  763. dataType: 'html',
  764. data: hierarchyParams,
  765. success: function(content) {
  766. target.children().fadeOut(effectTime, function() {
  767. target.children().remove();
  768. target.removeClass('is-processing');
  769. if (jQuery.trim(content) != '') {
  770. target.prepend(content);
  771. } else {
  772. target.prepend('<p class="messagebox info">No matches!</p>');
  773. }
  774. });
  775. }
  776. });
  777. lastLength = text.length;
  778. } else if ((text.length < autoCompleteMinChars) && lastLength >= autoCompleteMinChars) {
  779. loadHierarchy(id, $jq('#' + id).find('ol').eq(0));
  780. $jq('.resource-select.root').show();
  781. lastLength = 0;
  782. }
  783. }
  784. }, autoCompleteDelay);
  785. }
  786. /* ------------------- SoftWiki-Frickel-Funktion -------------------- */
  787. // prepare json string
  788. function getSoftWikiFrickelJson(tagsOnly) {
  789. var json = '[';
  790. for (var i = 0; i < selectedTags.length; ++i) {
  791. json += '"' + encodeURIComponent(selectedTags[i]) + '",';
  792. }
  793. if (tagsOnly) {
  794. if (json.length==1) json+=']';
  795. else json = json.substr(0,json.length - 1)+']';
  796. } else {
  797. json += '"' + encodeURIComponent(selectedResource) + '"]';
  798. }
  799. return json;
  800. }
  801. /* ------------------- SoftWiki-File Management Functions -------------------- */
  802. // add existing file
  803. function swAddExistingFile(event) {
  804. if (typeof($jq("#requirement").attr("about")) != 'undefined') {
  805. if ($jq("div.section-mainwindows").children("div.window").size() == 1) {
  806. $jq("div.section-mainwindows").append("<div class='window'></div>");
  807. }
  808. var targetwin = $jq("div.section-mainwindows").children("div.window").eq(1);
  809. if (targetwin) {
  810. replaceWindow(owUriBase + "softwiki/file/", "type=exist", targetwin);
  811. }
  812. }
  813. event.stopPropagation();
  814. }
  815. // add new file
  816. function swAddNewFile(event) {
  817. if (typeof($jq("#requirement").attr("about")) != 'undefined') {
  818. if ($jq("div.section-mainwindows").children("div.window").size() == 1) {
  819. $jq("div.section-mainwindows").append("<div class='window is-processing'></div>");
  820. }
  821. var instance = $jq("#requirement").attr("about");
  822. targetwin = $jq("div.section-mainwindows").children("div.window").eq(1);
  823. $jq.get(owUriBase + "softwiki/file/?type=new", '' , function(data, textStatus) {
  824. targetwin.replaceWith(data);
  825. $jq("#swFileForm").submit( function () {
  826. var options = {
  827. url: owUriBase + 'resource/file/?r=' + instance ,
  828. success: swUploadFile ,
  829. type: 'post'
  830. };
  831. $jq(this).ajaxSubmit(options);
  832. return false;
  833. });
  834. });
  835. }
  836. event.stopPropagation();
  837. }
  838. // add file with about
  839. function swFile(event) {
  840. var $target = $jq(event.target);
  841. $target.toggleClass('selected');
  842. event.stopPropagation();
  843. }
  844. // On Submit of file dialogs
  845. function swSubmitFile(event) {
  846. var $target = $jq(event.target);
  847. var resources = new Array();
  848. $jq('.swFile').each(function () {
  849. if ($jq(this).hasClass('selected')) {
  850. //alert('File' + $jq(this).attr('about'));
  851. resources.push($jq(this).attr('about'));
  852. }
  853. });
  854. if ($jq('.swFile.selected').size() != 0 && typeof($jq("#requirement").attr("about")) != 'undefined') {
  855. var resourcesjson = "[";
  856. for (var i = 0; i<resources.length ;i++) {
  857. resourcesjson = resourcesjson + "\"" + resources[i] + "\" , ";
  858. }
  859. resourcesjson = resourcesjson.substr(0,(resourcesjson.length) - 3);
  860. resourcesjson += "]";
  861. var instance = $jq("#requirement").attr("about");
  862. $jq("div.section-mainwindows").children('div.window').eq(0).addClass('is-processing');
  863. //replaceWindow(owUriBase + "softwiki/view/","r=" + instance);
  864. $jq.get(owUriBase + "softwiki/file/", "type=add&resources=" + resourcesjson,
  865. function(data) {
  866. var msg = data;
  867. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  868. function (data) {
  869. $jq("div.section-mainwindows").html(data);
  870. $jq("div.section-mainwindows").children("div.window").
  871. children(".content").prepend(msg);
  872. showComments();
  873. });
  874. });
  875. } else {
  876. showComments();
  877. }
  878. event.stopPropagation();
  879. }
  880. //On new file upload
  881. function swUploadFile(responseText, statusText) {
  882. if (typeof($jq("#requirement").attr("about")) != 'undefined') {
  883. var instance = $jq("#requirement").attr("about");
  884. $jq("div.section-mainwindows").children('div.window').eq(0).addClass('is-processing');
  885. $jq.get(
  886. owUriBase + "softwiki/view/?r=" + instance,
  887. function (data) {
  888. $jq("div.section-mainwindows").html(data);
  889. $jq("div.section-mainwindows > div.window:first > div.content")
  890. .prepend(responseText);
  891. }
  892. );
  893. }
  894. }
  895. // Unlink event (delete relation from req to file)
  896. function swFileUnlink (event) {
  897. $jq("div.section-mainwindows").children("div.window").toggleClass("is-processing");
  898. var resourcesjson = "[ \"" + $jq(event.target).parent().children().attr("about") + "\" ]";
  899. var instance = $jq("#requirement").attr("about");
  900. $jq.get(
  901. owUriBase + "softwiki/file/","type=unlink&resources=" + resourcesjson,
  902. function(data) {
  903. var msg = data;
  904. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  905. function (data) {
  906. $jq("div.section-mainwindows").html(data);
  907. $jq("div.section-mainwindows").children("div.window").
  908. children(".content").prepend(msg);
  909. });
  910. });
  911. event.stopPropagation();
  912. }
  913. /* ------------------- SoftWiki-Decision Management Functions -------------------- */
  914. // add existing Decision
  915. function swAddExistingDec(event) {
  916. if (typeof($jq("#requirement").attr("about")) != 'undefined') {
  917. if ($jq("div.section-mainwindows").children("div.window").size() == 1) {
  918. $jq("div.section-mainwindows").append("<div class='window'></div>");
  919. }
  920. var targetwin = $jq("div.section-mainwindows").children("div.window").eq(1);
  921. if (targetwin) {
  922. replaceWindow(owUriBase + "softwiki/dec/", "type=exist", targetwin);
  923. }
  924. }
  925. event.stopPropagation();
  926. }
  927. // add new Decision
  928. function swAddNewDec(event) {
  929. if (typeof($jq("#requirement").attr("about")) != 'undefined') {
  930. if ($jq("div.section-mainwindows").children("div.window").size() == 1) {
  931. $jq("div.section-mainwindows").append("<div class='window is-processing'></div>");
  932. }
  933. var instance = $jq("#requirement").attr("about");
  934. targetwin = $jq("div.section-mainwindows").children("div.window").eq(1);
  935. $jq.get(owUriBase + "softwiki/dec/?type=new", '' , function(data, textStatus) {
  936. targetwin.replaceWith(data);
  937. $jq("#swDecForm").submit( function () {
  938. var options = {
  939. url: owUriBase + 'resource/dec/?r=' + instance ,
  940. success: swUploadDec ,
  941. type: 'post'
  942. };
  943. $jq(this).ajaxSubmit(options);
  944. return false;
  945. });
  946. });
  947. }
  948. event.stopPropagation();
  949. }
  950. // add decision with about
  951. function swDec(event) {
  952. var $target = $jq(event.target);
  953. $target.toggleClass('selected');
  954. event.stopPropagation();
  955. }
  956. // On Submit of decision dialogs
  957. function swSubmitDec(event) {
  958. var $target = $jq(event.target);
  959. var resources = new Array();
  960. $jq('.swDec').each(function () {
  961. if ($jq(this).hasClass('selected')) {
  962. //alert('Dec' + $jq(this).attr('about'));
  963. resources.push($jq(this).attr('about'));
  964. }
  965. });
  966. if ($jq('.swDec.selected').size() != 0 && typeof($jq("#requirement").attr("about")) != 'undefined') {
  967. var resourcesjson = "[";
  968. for (var i = 0; i<resources.length ;i++) {
  969. resourcesjson = resourcesjson + "\"" + resources[i] + "\" , ";
  970. }
  971. resourcesjson = resourcesjson.substr(0,(resourcesjson.length) - 3);
  972. resourcesjson += "]";
  973. var instance = $jq("#requirement").attr("about");
  974. $jq("div.section-mainwindows").children('div.window').eq(0).addClass('is-processing');
  975. //replaceWindow(owUriBase + "softwiki/view/","r=" + instance);
  976. $jq.get(owUriBase + "softwiki/dec/", "type=add&resources=" + resourcesjson,
  977. function(data) {
  978. var msg = data;
  979. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  980. function (data) {
  981. $jq("div.section-mainwindows").html(data);
  982. $jq("div.section-mainwindows").children("div.window").
  983. children(".content").prepend(msg);
  984. showComments();
  985. });
  986. });
  987. } else {
  988. showComments();
  989. }
  990. event.stopPropagation();
  991. }
  992. //On new decision upload
  993. function swUploadDec(responseText, statusText) {
  994. if (typeof($jq("#requirement").attr("about")) != 'undefined') {
  995. var instance = $jq("#requirement").attr("about");
  996. $jq("div.section-mainwindows").children('div.window').eq(0).addClass('is-processing');
  997. $jq.get(
  998. owUriBase + "softwiki/view/?r=" + instance,
  999. function (data) {
  1000. $jq("div.section-mainwindows").html(data);
  1001. $jq("div.section-mainwindows > div.window:first > div.content")
  1002. .prepend(responseText);
  1003. }
  1004. );
  1005. }
  1006. }
  1007. // Unlink event (delete relation from req to decision)
  1008. function swDecUnlink (event) {
  1009. $jq("div.section-mainwindows").children("div.window").toggleClass("is-processing");
  1010. var resourcesjson = "[ \"" + $jq(event.target).attr("about") + "\" ]";
  1011. var instance = $jq("#requirement").attr("about");
  1012. $jq.get(
  1013. owUriBase + "softwiki/dec/","type=unlink&resources=" + resourcesjson,
  1014. function(data) {
  1015. var msg = data;
  1016. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  1017. function (data) {
  1018. $jq("div.section-mainwindows").html(data);
  1019. $jq("div.section-mainwindows").children("div.window").
  1020. children(".content").prepend(msg);
  1021. });
  1022. });
  1023. event.stopPropagation();
  1024. }
  1025. // Top link event (top relation from req to decision)
  1026. function swDecTop (event) {
  1027. $jq("div.section-mainwindows").children("div.window").toggleClass("is-processing");
  1028. var resourcesjson = "[ \"" + $jq(event.target).attr("about") + "\" ]";
  1029. var instance = $jq("#requirement").attr("about");
  1030. $jq.get(
  1031. owUriBase + "softwiki/dec/","type=top&resources=" + resourcesjson,
  1032. function(data) {
  1033. var msg = data;
  1034. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  1035. function (data) {
  1036. $jq("div.section-mainwindows").html(data);
  1037. $jq("div.section-mainwindows").children("div.window").
  1038. children(".content").prepend(msg);
  1039. });
  1040. });
  1041. event.stopPropagation();
  1042. }
  1043. // Down link event (delete relation from req to decision)
  1044. function swDecDown (event) {
  1045. $jq("div.section-mainwindows").children("div.window").toggleClass("is-processing");
  1046. var resourcesjson = "[ \"" + $jq(event.target).attr("about") + "\" ]";
  1047. var instance = $jq("#requirement").attr("about");
  1048. $jq.get(
  1049. owUriBase + "softwiki/dec/","type=down&resources=" + resourcesjson,
  1050. function(data) {
  1051. var msg = data;
  1052. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  1053. function (data) {
  1054. $jq("div.section-mainwindows").html(data);
  1055. $jq("div.section-mainwindows").children("div.window").
  1056. children(".content").prepend(msg);
  1057. });
  1058. });
  1059. event.stopPropagation();
  1060. }
  1061. // Un-Top link event (top relation from req to decision)
  1062. function swDecUnTop (event) {
  1063. $jq("div.section-mainwindows").children("div.window").toggleClass("is-processing");
  1064. var resourcesjson = "[ \"" + $jq(event.target).attr("about") + "\" ]";
  1065. var instance = $jq("#requirement").attr("about");
  1066. $jq.get(
  1067. owUriBase + "softwiki/dec/","type=untop&resources=" + resourcesjson,
  1068. function(data) {
  1069. var msg = data;
  1070. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  1071. function (data) {
  1072. $jq("div.section-mainwindows").html(data);
  1073. $jq("div.section-mainwindows").children("div.window").
  1074. children(".content").prepend(msg);
  1075. });
  1076. });
  1077. event.stopPropagation();
  1078. }
  1079. // Un-Down link event (down relation from req to decision)
  1080. function swDecUnDown (event) {
  1081. $jq("div.section-mainwindows").children("div.window").toggleClass("is-processing");
  1082. var resourcesjson = "[ \"" + $jq(event.target).attr("about") + "\" ]";
  1083. var instance = $jq("#requirement").attr("about");
  1084. $jq.get(
  1085. owUriBase + "softwiki/dec/","type=undown&resources=" + resourcesjson,
  1086. function(data) {
  1087. var msg = data;
  1088. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  1089. function (data) {
  1090. $jq("div.section-mainwindows").html(data);
  1091. $jq("div.section-mainwindows").children("div.window").
  1092. children(".content").prepend(msg);
  1093. });
  1094. });
  1095. event.stopPropagation();
  1096. }
  1097. // Link event (add relation from req to decision)
  1098. function swDecLink (event) {
  1099. $jq("div.section-mainwindows").children("div.window").toggleClass("is-processing");
  1100. var resourcesjson = "[ \"" + $jq(event.target).attr("about") + "\" ]";
  1101. var instance = $jq("#requirement").attr("about");
  1102. //alert(resourcesjson + ' ' + instance);
  1103. $jq.get(
  1104. owUriBase + "softwiki/dec/","type=link&resources=" + resourcesjson,
  1105. function(data) {
  1106. var msg = data;
  1107. $jq.get(owUriBase + "softwiki/view/?r=" + instance,
  1108. function (data) {
  1109. $jq("div.section-mainwindows").html(data);
  1110. $jq("div.section-mainwindows").children("div.window").
  1111. children(".content").prepend(msg);
  1112. });
  1113. });
  1114. event.stopPropagation();
  1115. }
  1116. /* -------------------------- Hierarchy Dropdown --------------------------- */
  1117. $jq(document).ready(function() {
  1118. $jq('#rtopic-select').livequery(function() {
  1119. $jq(this).dropdownHierarchy({
  1120. url: owUriBase + 'service/gettreenodecontent/',
  1121. nodeType: hierarchyParams.nt,
  1122. subRelation: hierarchyParams.sr,
  1123. instanceRelation: hierarchyParams.ir
  1124. });
  1125. });
  1126. })
  1127. function repositionOverlay() {
  1128. $jq('#rtopic-select').css('width', '20em');
  1129. var offset = $jq('#rtopic-select').offset();
  1130. $jq('#rtopic-select-overlay').css('top', offset.top + 'px');
  1131. $jq('#rtopic-select-overlay').css('width', '16em');
  1132. $jq('#rtopic-tree-container').css('top', offset.top + $jq('#rtopic-select').height() + 3 + 'px');
  1133. $jq('#rtopic-tree-container').css('width', '20em');
  1134. if ($jq.browser.msie && $jq.browser.version == '6.0') {
  1135. $jq('#rtopic-select-overlay-iframe')
  1136. .css('top', offset.top + 'px')
  1137. .css('width', '16em');
  1138. }
  1139. }
  1140. jQuery.fn.dropdownHierarchy = function(settings) {
  1141. return this.each(function() {
  1142. var select = $jq(this);
  1143. var offset = select.offset();
  1144. if (select.attr('disabled')) {
  1145. $jq('#rtopic-select-overlay').addClass('disabled');
  1146. }
  1147. $jq('body').append('<div id="rtopic-select-overlay"></div><div id="rtopic-tree-container"></div>');
  1148. $jq('#rtopic-select-overlay')
  1149. .css('position', 'absolute')
  1150. .css('background-image', 'url("' + owUriBase + 'plugins/SoftWiki/trans.gif")')
  1151. .css('background-repeat', 'repeat')
  1152. .css('left', offset.left + 'px')
  1153. .css('top', offset.top + 'px')
  1154. .css('width', '20em')
  1155. .css('height', select.height() + 3 + 'px')
  1156. .css('padding-left', '0.5em')
  1157. .css('zIndex', '101')
  1158. .width(select.width());
  1159. $jq('#rtopic-tree-container')
  1160. .css('position', 'absolute')
  1161. .css('border', '1px solid #ccc')
  1162. .css('display', 'none')
  1163. .css('left', offset.left + 'px')
  1164. .css('top', offset.top + select.height() + 3 + 'px')
  1165. .css('height', '20em')
  1166. .css('font-size', '0.8em')
  1167. .css('opacity', '0.96')
  1168. .css('overflow', 'auto')
  1169. .css('background-color', '#fff')
  1170. .css('zIndex', '101')
  1171. .width(select.width() - 2);
  1172. // IE6 specific hack
  1173. if ($jq.browser.msie && $jq.browser.version == '6.0') {
  1174. $jq('body').append('<iframe id="rtopic-select-overlay-iframe"></iframe>');
  1175. $jq('#rtopic-select-overlay-iframe')
  1176. .css('position', 'absolute')
  1177. .css('top', offset.top + 'px')
  1178. .css('left', offset.left + 'px')
  1179. .css('height', select.height() + 3 + 'px')
  1180. .css('width', '16em')
  1181. .css('zIndex', '100')
  1182. .css('filter', 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)');
  1183. $jq('#rtopic-select-overlay')
  1184. .css('background-image', 'url("' + owUriBase + 'plugins/SoftWiki/select.gif")')
  1185. .css('background-repeat', 'no-repeat')
  1186. .css('width', '16em');
  1187. }
  1188. jQuery('.tree-item').livequery('click', function(event) {
  1189. select.find('option').remove();
  1190. var text = jQuery.trim(jQuery(this).text().replace(/\(\d\)/, ''));
  1191. select.append('<option value="' + jQuery(this).attr('about') + '" selected="selected">' + text + '</option>');
  1192. // IE6 specific hack
  1193. if ($jq.browser.msie && $jq.browser.version == '6.0') {
  1194. $jq('#rtopic-select-overlay').text(text);
  1195. }
  1196. jQuery('#rtopic-tree-container').fadeOut(effectTime);
  1197. event.stopPropagation();
  1198. })
  1199. jQuery('#rtopic-tree-container a').livequery('mouseover', function(event) {
  1200. jQuery(this).addClass('selected');
  1201. })
  1202. jQuery('#rtopic-tree-container a').livequery('mouseout', function(event) {
  1203. if (jQuery(this).attr('about') != jQuery('#rtopic-select option').val()) {
  1204. jQuery(this).removeClass('selected');
  1205. }
  1206. })
  1207. // hide on any click
  1208. jQuery('html').click(function(event) {
  1209. event.stopPropagation();
  1210. if (jQuery('#rtopic-tree-container').css('display') != 'none') {
  1211. jQuery('#rtopic-tree-container').fadeOut(effectTime);
  1212. jQuery('#rtopic-tree-container').html('');
  1213. }
  1214. })
  1215. // load hierarchy on click
  1216. jQuery('#rtopic-select-overlay').mousedown(function(event) {
  1217. jQuery('#rtopic-select').mousedown();
  1218. });
  1219. jQuery('#rtopic-select').parents('form').mousemove(function(event) {
  1220. repositionOverlay();
  1221. });
  1222. jQuery('#rtopic-select').mousedown(function(event) {
  1223. if (!jQuery(this).hasClass('disabled') && jQuery('#rtopic-tree-container').css('display') != 'block') {
  1224. var url = settings.url
  1225. + '?complete=true&javascript=true'
  1226. + '&nt=' + encodeURIComponent(settings.nodeType)
  1227. + '&sr=' + encodeURIComponent(settings.subRelation)
  1228. + '&ir=' + encodeURIComponent(settings.instanceRelation);
  1229. jQuery('#rtopic-tree-container').load(url, function() {
  1230. jQuery('#rtopic-tree-container').fadeIn(effectTime);
  1231. var current = jQuery('#rtopic-select option').val();
  1232. jQuery('#rtopic-tree-container').find('a[@about="' + current + '"]').addClass('selected');
  1233. });
  1234. }
  1235. event.preventDefault();
  1236. event.stopPropagation();
  1237. })
  1238. })
  1239. }
  1240. /* ------------------ Requirement Description Auto Resize ------------------ */
  1241. $jq(document).ready(function() {
  1242. /*$jq('#rdescription').livequery(function() {
  1243. $jq(this).autoResizeTextArea()
  1244. });*/
  1245. });
  1246. jQuery.fn.autoResizeTextArea = function()
  1247. {
  1248. return this.each(function() {
  1249. new jQuery.autoResizeTextArea(this);
  1250. });
  1251. };
  1252. jQuery.autoResizeTextArea = function(elem)
  1253. {
  1254. // quick n dirty msie hack :(
  1255. if (jQuery.browser.msie) {
  1256. jQuery(elem).css('line-height', '100.01%');
  1257. }
  1258. this.dummy = null;
  1259. this.intervall = null;
  1260. this.line_height = parseInt(jQuery(elem).css('line-height'));
  1261. this.min_height = parseInt(jQuery(elem).css('min-height'));
  1262. this.max_height = parseInt(jQuery(elem).css('max-height'));
  1263. this.textarea = jQuery(elem);
  1264. this.init();
  1265. };
  1266. jQuery.autoResizeTextArea.fn = jQuery.autoResizeTextArea.prototype = { autoResizeTextArea: '0.1' };
  1267. jQuery.autoResizeTextArea.fn.extend = jQuery.autoResizeTextArea.extend = jQuery.extend;
  1268. var resizeCount = 0;
  1269. jQuery.autoResizeTextArea.fn.extend(
  1270. {
  1271. init: function()
  1272. {
  1273. var self = this;
  1274. this.textarea.css({overflow: 'hidden', display: 'block'});
  1275. this.textarea
  1276. .bind('keyup', function() {
  1277. var localCount = ++resizeCount;
  1278. window.setTimeout(function() {
  1279. if (localCount == resizeCount) {
  1280. self.checkExpand();
  1281. }
  1282. }, 300)
  1283. });
  1284. this.checkExpand();
  1285. },
  1286. checkExpand: function()
  1287. {
  1288. if (this.dummy == null) {
  1289. this.dummy = $jq('<div></div>');
  1290. this.dummy.css({
  1291. 'font-size' : this.textarea.css('font-size'),
  1292. 'font-family': this.textarea.css('font-family'),
  1293. 'width' : this.textarea.css('width'),
  1294. 'padding' : this.textarea.css('padding'),
  1295. 'line-height': this.line_height + 'px',
  1296. 'overflow-x' : 'hidden',
  1297. 'display' : 'none',
  1298. 'position' : 'absolute',
  1299. 'top' : 0,
  1300. 'left' : '-9999px'
  1301. }).appendTo('body');
  1302. }
  1303. var html = this.textarea.val().replace(/\n/g, '<br>n');
  1304. if (this.dummy.html() != html || html=='') {
  1305. this.dummy.html(html);
  1306. var dHeight = this.dummy.height();
  1307. var tHeight = this.textarea.height();
  1308. var newHeight = dHeight + 2*(this.line_height);
  1309. if (!isNaN(this.max_height) && (newHeight > this.max_height)) {
  1310. this.textarea.css('overflow-y', 'auto');
  1311. } else {
  1312. this.textarea.css('overflow-y', 'hidden');
  1313. if ((tHeight < newHeight) || (dHeight < tHeight)) {
  1314. //this.textarea.animate({height: newHeight + 'px'}, 100);
  1315. this.textarea.css('height', newHeight + 'px');
  1316. // HACK:
  1317. repositionOverlay();
  1318. }
  1319. }
  1320. }
  1321. }
  1322. });
  1323. /*function swReqDescAutoResize(event) {
  1324. resizeTextArea($jq('#rdescription'));return;
  1325. // only do something if pressed key was one of return, delete or entf
  1326. if ((event.which == 13) || (event.which == 8) || (event.which == 46)) {
  1327. resizeTextArea($jq('#rdescription'));
  1328. }
  1329. }
  1330. function resizeTextArea(elem) {
  1331. var minNRows = 4;
  1332. var maxNRows = 20;
  1333. var tArea = elem;
  1334. var tVal = tArea.val();
  1335. var nRows = parseInt(tArea.attr("rows"));
  1336. var dummy = jQuery.data(tArea.get(0), 'dummyElem');
  1337. if (typeof dummy == 'undefined') {
  1338. dummy = $jq('<div></div>');
  1339. dummy.css({
  1340. 'font-size' : tArea.css('font-size'),
  1341. 'font-family': tArea.css('font-family'),
  1342. 'width' : tArea.css('width'),
  1343. 'padding' : tArea.css('padding'),
  1344. 'line-height': tArea.css('line-height'),
  1345. 'overflow-x' : 'hidden',
  1346. 'display' : 'block',
  1347. 'position' : 'absolute',
  1348. 'top' : 0,
  1349. 'left' : '0px'
  1350. }).appendTo('body');
  1351. jQuery.data(tArea.get(0), 'dummyElem', dummy);
  1352. }
  1353. var html = tVal.replace(/\n/g, '<br>');
  1354. if (dummy.html() != html) {
  1355. dummy.html(html);
  1356. var dHeight = dummy.height();
  1357. var tHeight = tArea.height();
  1358. var lHeight = parseInt(tArea.css('line-height'));
  1359. if (tHeight != (dHeight + lHeight)) {
  1360. var newHeight = parseInt((dHeight+lHeight)/lHeight);
  1361. if (newHeight < minNRows) {
  1362. tArea.attr('rows', minNRows);
  1363. } else if (newHeight > maxNRows) {
  1364. tArea.attr('rows', maxNRows);
  1365. } else {
  1366. tArea.attr('rows', newHeight);
  1367. }
  1368. }
  1369. }
  1370. return;
  1371. dummy.height();
  1372. tArea.focus();
  1373. return;
  1374. while ((dummy.height() + tArea.css('line-height')) >= tArea.height()) {
  1375. var n = parseInt(tArea.attr('rows'));
  1376. if (n >= maxNRows) {
  1377. break;
  1378. }
  1379. tArea.attr('rows', (n+1));
  1380. }
  1381. dummy.remove();
  1382. return;
  1383. var eolCount = 1;
  1384. for (var i=0; i<(tVal.length-1); ++i) {
  1385. if (tVal.charAt(i) == "\n") {
  1386. eolCount++;
  1387. }
  1388. }
  1389. if ((eolCount+1) >= nRows) {
  1390. tArea.attr("rows", (nRows + ((eolCount+1) - nRows) + 1));
  1391. } else {
  1392. var diff = nRows - (eolCount+2);
  1393. if ((nRows-diff) >= minNRows) {
  1394. tArea.attr("rows", (nRows - diff));
  1395. } else {
  1396. tArea.attr("rows", minNRows);
  1397. }
  1398. }
  1399. }*/
  1400. /* ------------------ tagging functionality -------------------------------- */
  1401. function addTag(event) {
  1402. var addElem = $jq("#rtagsNew");
  1403. var tagList = $jq('#rtags');
  1404. var tagVal = addElem.attr('value');
  1405. var tagButtonElem = $jq('#rtagsButton');
  1406. function animateError() {
  1407. addElem.animate({backgroundColor: '#f00', opacity: 0.6}, 100);
  1408. addElem.animate({backgroundColor: '#fff', opacity: 1.0}, 600);
  1409. }
  1410. function isValidTag() {
  1411. if ((typeof tagVal != 'undefined') && (tagVal.replace(/\s/g, "") != "")) {
  1412. var tags = tagList.children('span');
  1413. var isNew = true;
  1414. for (var i=0; i<tags.length; ++i) {
  1415. curTagText = tags.children('span').eq(i).text();
  1416. if (curTagText.toLowerCase() == tagVal.toLowerCase()) {
  1417. isNew = false;
  1418. break;
  1419. }
  1420. }
  1421. if (isNew == true) {
  1422. return true;
  1423. }
  1424. }
  1425. return false;
  1426. }
  1427. if ((event.which == 13)) {
  1428. if (!(addElem.hasClass('disabled'))) {
  1429. if (isValidTag()) {
  1430. var addVal = '<span class="wasDisabled token" >' +
  1431. '<span class="tag">' + tagVal + '</span>' +
  1432. '<span class="removetag"></span></span>';
  1433. tagButtonElem.eq(0).after(addVal);
  1434. } else {
  1435. animateError();
  1436. }
  1437. // clear the input field and disable button again
  1438. addElem.removeAttr('value');
  1439. tagButtonElem.addClass('disabled').removeClass('wasDisabled');
  1440. }
  1441. } else {
  1442. if (isValidTag()) {
  1443. tagButtonElem.removeClass('disabled').addClass('wasDisabled');
  1444. } else {
  1445. tagButtonElem.addClass('disabled').removeClass('wasDisabled');
  1446. }
  1447. }
  1448. }
  1449. function addTagWithButton(event) {
  1450. var addElem = $jq("#rtagsNew");
  1451. var tagVal = addElem.attr('value');
  1452. var tagButtonElem = $jq('#rtagsButton');
  1453. if (!tagButtonElem.hasClass('disabled')) {
  1454. var addVal = '<span class="wasDisabled token" >' +
  1455. '<span class="tag">' + tagVal + '</span>' +
  1456. '<span class="removetag"></span></span>';
  1457. tagButtonElem.eq(0).after(addVal);
  1458. // clear the input field and disable button again
  1459. addElem.removeAttr('value');
  1460. tagButtonElem.addClass('disabled').removeClass('wasDisabled');
  1461. }
  1462. }
  1463. function changeVersionButton(event) {
  1464. //var addElem = $jq("#rtagsNew");
  1465. //var tagVal = addElem.attr('value');
  1466. var VersionElem = $jq('#rVersionButton');
  1467. var DescriptionElem = document.getElementById("rversions-select");
  1468. var editorInstance = FCKeditorAPI.GetInstance('rdescription');
  1469. var EditElem = document.getElementById('rdescription');
  1470. if (!VersionElem.hasClass('disabled')) {
  1471. // find the selectet Version Element
  1472. for (var loop=0; loop<DescriptionElem.options.length; loop++) {
  1473. if (DescriptionElem.options[loop].selected) {
  1474. editorInstance.InsertHtml(DescriptionElem.options[loop].text);
  1475. }
  1476. }
  1477. }
  1478. }
  1479. function addTagWithClickOnSuggestion(clickedElem) {
  1480. var addElem = $jq("#rtagsNew");
  1481. var tagVal = clickedElem.text();
  1482. var tagButtonElem = $jq('#rtagsButton');
  1483. if (!tagButtonElem.hasClass('disabled')) {
  1484. var addVal = '<span class="wasDisabled token" >' +
  1485. '<span class="tag">' + tagVal + '</span>' +
  1486. '<span class="removetag"></span></span>';
  1487. tagButtonElem.eq(0).after(addVal);
  1488. // clear the input field and disable button again
  1489. addElem.removeAttr('value');
  1490. tagButtonElem.addClass('disabled').removeClass('wasDisabled');
  1491. }
  1492. $jq('#rtagsNew-overlay').remove();
  1493. }
  1494. function suggestTags(event) {
  1495. // remove suggestions on escape
  1496. if (event.which == 27) {
  1497. $jq('#rtagsNew-overlay').remove();
  1498. return;
  1499. }
  1500. // catch arrow down
  1501. else if (event.which == 40) {
  1502. var selectedElem = $jq('#rtagsNew-overlay').children('ul').children('li.selected');
  1503. // check whether overlay exists
  1504. if (typeof $jq('#rtagsNew-overlay').get(0) != 'undefined') {
  1505. // check whether any item is selected
  1506. if (typeof selectedElem.get(0) != 'undefined') {
  1507. //check whether next item exists
  1508. if (typeof selectedElem.next('li').get(0) != 'undefined') {
  1509. selectedElem.removeClass('selected');
  1510. selectedElem.next('li').eq(0).addClass('selected');
  1511. $jq('#rtagsNew').attr('value', selectedElem.next('li').eq(0).text());
  1512. } else {
  1513. selectedElem.removeClass('selected');
  1514. $jq('#rtagsNew').attr('value', jQuery.data($jq('#rtagsNew').get(0), 'userTypedValue'));
  1515. }
  1516. }
  1517. // overlay exists, but nothing is selected -> select the first item
  1518. else {
  1519. var suggestItems = $jq('#rtagsNew-overlay').children('ul').children('li');
  1520. suggestItems.eq(0).addClass('selected');
  1521. $jq('#rtagsNew').attr('value', suggestItems.eq(0).text());
  1522. }
  1523. return;
  1524. }
  1525. }
  1526. // catch arrow up
  1527. else if (event.which == 38) {
  1528. var selectedElem = $jq('#rtagsNew-overlay').children('ul').children('li.selected');
  1529. // check whether overlay exists
  1530. if (typeof $jq('#rtagsNew-overlay').get(0) != 'undefined') {
  1531. // check whether any item is selected
  1532. if (typeof selectedElem.get(0) != 'undefined') {
  1533. //check whether previous item exists
  1534. if (typeof selectedElem.prev('li').get(0) != 'undefined') {
  1535. selectedElem.removeClass('selected');
  1536. selectedElem.prev('li').eq(0).addClass('selected');
  1537. $jq('#rtagsNew').attr('value', selectedElem.prev('li').eq(0).text());
  1538. } else {
  1539. selectedElem.removeClass('selected');
  1540. $jq('#rtagsNew').attr('value', jQuery.data($jq('#rtagsNew').get(0), 'userTypedValue'));
  1541. }
  1542. }
  1543. // overlay exists, but nothing is selected -> select the last item
  1544. else {
  1545. var suggestItems = $jq('#rtagsNew-overlay').children('ul').children('li');
  1546. var lastNumber = suggestItems.length - 1;
  1547. suggestItems.eq(lastNumber).addClass('selected');
  1548. $jq('#rtagsNew').attr('value', suggestItems.eq(lastNumber).text());
  1549. }
  1550. return;
  1551. }
  1552. }
  1553. // catch right arrow
  1554. else if (event.which == 39) {
  1555. var selectedElem = $jq('#rtagsNew-overlay').children('ul').children('li.selected');
  1556. if (typeof selectedElem.get(0) != 'undefined') {
  1557. $jq('#rtagsNew').attr('value', selectedElem.text());
  1558. jQuery.data($jq('#rtagsNew').get(0), 'userTypedValue', $jq('#rtagsNew').attr('value'));
  1559. $jq('#rtagsNew-overlay').remove();
  1560. }
  1561. return;
  1562. }
  1563. // catch enter button
  1564. else if (event.which == 13) {
  1565. var selectedElem = $jq('#rtagsNew-overlay').children('ul').children('li.selected');
  1566. if (typeof selectedElem.get(0) != 'undefined') {
  1567. $jq('#rtagsNew').attr('value', selectedElem.text());
  1568. $jq('#rtagsNew-overlay').remove();
  1569. }
  1570. return;
  1571. }
  1572. // catch the left arrow (do not store current value and do not suggest something new)
  1573. else if (event.which == 37) {
  1574. return;
  1575. }
  1576. // now that every special button is checked -> store the user typed content of the input field in order to get it
  1577. // back later
  1578. else {
  1579. jQuery.data($jq('#rtagsNew').get(0), 'userTypedValue', $jq('#rtagsNew').attr('value'));
  1580. }
  1581. var MAX_COUNT = 10;
  1582. var inputElem = $jq('#rtagsNew');
  1583. var content = '<ul class="tag_suggest">';
  1584. var data = jQuery.data($jq('#rtagsNew').get(0), 'suggestTags');
  1585. var searchString = inputElem.attr('value');
  1586. var count = 0;
  1587. for (var i=0; i<data.length; ++i) {
  1588. if (count >= MAX_COUNT) {
  1589. break;
  1590. }
  1591. if (typeof searchString == 'undefined') {
  1592. break;
  1593. }
  1594. searchString = searchString.toLowerCase();
  1595. var currentTag = data[i];
  1596. // suggested tag can't be shorter than search string
  1597. if (currentTag.length < searchString.length) {
  1598. continue;
  1599. }
  1600. var matches = 0;
  1601. for (var j=0; j<searchString.length; ++j) {
  1602. if (currentTag.toLowerCase().charAt(j) < searchString.charAt(j)) {
  1603. matches = -1;
  1604. break;
  1605. }
  1606. if (currentTag.toLowerCase().charAt(j) > searchString.charAt(j)) {
  1607. matches = 1;
  1608. break;
  1609. }
  1610. }
  1611. if (matches < 0) {
  1612. continue;
  1613. } else if (matches > 0) {
  1614. break;
  1615. } else {
  1616. var usedTags = $jq('#rtags').children('span').children('span.tag');
  1617. var alreadyUsed = false;
  1618. for (var j=0; j<usedTags.length; ++j) {
  1619. if (currentTag.toLowerCase() == usedTags.eq(j).text().toLowerCase()) {
  1620. alreadyUsed = true;
  1621. break;
  1622. }
  1623. }
  1624. if (alreadyUsed) {
  1625. continue;
  1626. }
  1627. content += '<li><b>' + data[i].substring(0, searchString.length) + '</b>' + data[i].substring(searchString.length) + '</li>';
  1628. count++;
  1629. }
  1630. }
  1631. content += '</ul>';
  1632. var overlay = $jq('#rtagsNew-overlay');
  1633. var offset = inputElem.offset();
  1634. // only show overlay if there is at least one suggestion
  1635. if (count > 0) {
  1636. overlay.remove();
  1637. overlay = $jq('<div id="rtagsNew-overlay"></div>');
  1638. overlay .css('position', 'absolute')
  1639. .css('top', (offset.top + inputElem.height() + 6) + 'px')
  1640. .css('left', (offset.left) + 'px')
  1641. .css('width', (inputElem.width()) + 'px')
  1642. .css('min-height', '40px')
  1643. .css('background-color', '#fff')
  1644. .css('padding', '2px')
  1645. .css('border', '1px solid #ccc')
  1646. .css('opacity', '0.9');
  1647. $jq('body').append(overlay);
  1648. overlay.append(content);
  1649. } else {
  1650. overlay.remove();
  1651. }
  1652. }
  1653. /* ------------------- Input Delete Button -------------------- */
  1654. $jq(document).ready(function() {
  1655. $jq('.hierarchy-search-input').clearInput();
  1656. })
  1657. jQuery.fn.clearInput = function() {
  1658. return this.each(function() {
  1659. var input = jQuery(this);
  1660. input.removeClass('width95');
  1661. input.removeClass('width90');
  1662. input.css('width', '85%');
  1663. var link = jQuery('<a><img src="' + owThemeBase + 'images/icon-clear.png" alt="clear"/></a>');
  1664. link.css('float', 'right');
  1665. var marg = (input.height() - 12) / 2 + 1;
  1666. link.css('margin-top', marg + 'px');
  1667. link.css('left', '-' + (12 + marg) + 'px');
  1668. link.mouseover(function() {
  1669. jQuery(this).children('img').attr('src', owThemeBase + 'images/icon-clear-hover.png');
  1670. }).mouseout(function() {
  1671. jQuery(this).children('img').attr('src', owThemeBase + 'images/icon-clear.png');
  1672. })
  1673. link.click(function() {
  1674. var input = jQuery(this).nextAll('input');
  1675. input.val('');
  1676. input.focus();
  1677. var id = input.attr('id').replace(/-search-input/, '');
  1678. // test
  1679. if (selectedResource == 'http://ns.softwiki.de/req/Requirement') {
  1680. $jq('.resource-select.root').addClass('selected');
  1681. }
  1682. loadHierarchy(id, jQuery('div#' + id).find('ol').eq(0));
  1683. // select root #50
  1684. $jq('.resource-select.root').click();
  1685. })
  1686. input.before(link);
  1687. })
  1688. }
  1689. jQuery.fn.clearTagSearchInput = function() {
  1690. return this.each(function() {
  1691. var input = jQuery(this);
  1692. input.removeClass('width95');
  1693. input.removeClass('width90');
  1694. input.css('width', '85%');
  1695. var link = jQuery('<a><img src="' + owThemeBase + 'images/icon-clear.png" alt="clear"/></a>');
  1696. link.css('float', 'right');
  1697. var marg = (input.height() - 12) / 2 + 1;
  1698. link.css('margin-top', marg + 'px');
  1699. link.css('left', '-' + (12 + marg) + 'px');
  1700. link.mouseover(function() {
  1701. jQuery(this).children('img').attr('src', owThemeBase + 'images/icon-clear-hover.png');
  1702. }).mouseout(function() {
  1703. jQuery(this).children('img').attr('src', owThemeBase + 'images/icon-clear.png');
  1704. })
  1705. link.click(function() {
  1706. var input = jQuery(this).nextAll('input');
  1707. input.val('');
  1708. input.focus();
  1709. var id = input.attr('id').replace(/search-input/, '');
  1710. filterTags();
  1711. })
  1712. input.before(link);
  1713. })
  1714. }
  1715. function filterTags()
  1716. {
  1717. $jq('#tags div ol').hide();
  1718. //look at checkboxes
  1719. if ($jq('.toggleDefinedTags').attr('checked')) $jq(".tag.tagGreen").parent().show();
  1720. else $jq(".tag.tagGreen").parent().hide();
  1721. if ($jq('.toggleUndefinedTags').attr('checked')) $jq(".tag.tagBlue").parent().show();
  1722. else $jq(".tag.tagBlue").parent().hide();
  1723. if ($jq('.toggleOtherDefinedTags').attr('checked')) $jq(".tag.tagRed").parent().show();
  1724. else $jq(".tag.tagRed").parent().hide();
  1725. //look at search input
  1726. var text=$jq('input#tag-search-input').val();
  1727. if ( text.length>0 && text != $jq('label[@for="tag-search-input"]').html() ) {
  1728. $jq(".tag").each(function(i,val) {
  1729. var cut = $jq(val).children("span").text().length;
  1730. var fulltext = $jq(val).text();
  1731. var tagtext = fulltext.substring(0,fulltext.length - cut);
  1732. var tagRegExp = new RegExp(text,"i");
  1733. if (tagRegExp.test(tagtext)) {
  1734. // do nothing
  1735. } else {
  1736. // Hide this tag (Not found)
  1737. $jq(".tag").eq(i).hide();
  1738. }
  1739. });
  1740. }
  1741. $jq('#tags div ol').show();
  1742. }
  1743. /*
  1744. * Creates an UI Window as an Overlay
  1745. * @param event The click event from where the overlay was started
  1746. * @param url A gettable URL which is loaded for the window content
  1747. * @param params The URL parameters as key/value array
  1748. */
  1749. function createOverlayWindow(event, url, params) {
  1750. // remove all other overlays
  1751. $jq('.overlay.window').remove();
  1752. var menuX = event.pageX - 10;
  1753. var menuY = event.pageY - 50;
  1754. $jq('#overlays').attr("style","height: "+$jq(document).height()+"px; opacity: 0.5;background-color:#AAAAAA;left:0;position:absolute;top:0;width:100%;z-index:90;display:none;");
  1755. $jq('#overlays').fadeIn("normal");
  1756. $jq('#overlays').after(''+
  1757. '<div class="window overlay is-processing" '+
  1758. 'style="display: none; width: 35em; position: absolute; '+
  1759. 'z-index: 10; top: '+menuY+'px; left: '+menuX+'px;">'+
  1760. '<h2 style="cursor: move;" class="title">loading ...</h2>'+
  1761. '<div class="content">'+
  1762. '</div>'+
  1763. '</div>');
  1764. var targetwin = $jq('#overlays').next();
  1765. targetwin.attr("style","z-index: 100; opacity: 1.0; width: 35em; position: absolute; "+
  1766. "z-index: 100; top: "+menuY+"px; left: "+menuX+"px;");
  1767. targetwin.fadeIn("normal");
  1768. // put the target window into the temp box (for this ajax uri)
  1769. // setAutoID(targetwin);
  1770. $jq.ajax({
  1771. url: url,
  1772. data: params,
  1773. dataType: 'html',
  1774. success: function(content) {
  1775. targetwin.children(".content").prepend($jq(content).children(".content").html());
  1776. targetwin.children(".title").text($jq(content).children(".title").text());
  1777. targetwin.removeClass('is-processing');
  1778. enhanceWindow(targetwin);
  1779. targetwin.draggable({handle: '.title', containment: 'document'});
  1780. }
  1781. });
  1782. event.stopPropagation();
  1783. }
  1784. //its a hack, don't know better at the moment
  1785. function swRelationEdit(event) {
  1786. var params = "";
  1787. params += "r=" + encodeURIComponent($jq("#requirement").attr("about"))
  1788. + "&object=" + encodeURIComponent($jq(event.target).parents("td").attr("about"))
  1789. + "&r_title=" + encodeURIComponent($jq("#noneditDescription h3").text())
  1790. + "&object_title="
  1791. + encodeURIComponent($jq(event.target).parents("tr").eq(0).children("td").eq(2).children("p").text());
  1792. createOverlayWindow(event,owUriBase + "softwiki/relationsservice",params);
  1793. }
  1794. function stripTags(oldString){
  1795. return oldString.replace(/<\/?[^>]+>/gi, "");
  1796. }
  1797. function stripGreenTags(oldString){
  1798. return oldString.replace(/<\/?font[^>]*>/gi, "");
  1799. }
  1800. //FCKeditor specific functions///////////////////
  1801. /*$jq("#rdescription___Frame").livequery(function() {
  1802. });*/
  1803. /*
  1804. function disableEditor(){
  1805. var oFCKeditor = FCKeditorAPI.GetInstance('rdescription');
  1806. disableFCKeditor(oFCKeditor);
  1807. }
  1808. function enableEditor(){
  1809. var oFCKeditor = FCKeditorAPI.GetInstance('rdescription');
  1810. enableFCKeditor(oFCKeditor);
  1811. }
  1812. // what do we do with the toolbar when disabling the editor. Possibilities are 'disable', 'hide', 'collapse'.
  1813. // When collapsed the toolbar can be expanded again by the user, but he'll find a disabled toolbar.
  1814. var toolbarDisabledState = "disable";
  1815. function disableFCKeditor(editorInstance){
  1816. if ((!document.all && editorInstance.EditorDocument.designMode.toLowerCase() != "off") || (document.all && editorInstance.EditorDocument.body.disabled == false))
  1817. {
  1818. //opacity
  1819. document.getElementById('rdescription___Frame').contentWindow.document.getElementsByTagName('html')[0].getElementsByTagName('body')[0].style.MozOpacity=0.5;
  1820. // disable the editArea
  1821. if (document.all)
  1822. {
  1823. editorInstance.EditorDocument.body.disabled = true;
  1824. }
  1825. else
  1826. {
  1827. editorInstance.EditorDocument.designMode = "off";
  1828. }
  1829. // disable the toolbar
  1830. switch (toolbarDisabledState)
  1831. {
  1832. case "collapse" : editorInstance.EditorWindow.parent.FCK.ToolbarSet._ChangeVisibility(true);
  1833. case "disable" : editorInstance.EditorWindow.parent.FCK.ToolbarSet.Disable();
  1834. buttonRefreshStateClone = editorInstance.EditorWindow.parent.FCKToolbarButton.prototype.RefreshState;
  1835. specialComboRefreshStateClone = editorInstance.EditorWindow.parent.FCKToolbarSpecialCombo.prototype.RefreshState;
  1836. editorInstance.EditorWindow.parent.FCKToolbarButton.prototype.RefreshState = function(){return false;};
  1837. editorInstance.EditorWindow.parent.FCKToolbarSpecialCombo.prototype.RefreshState = function(){return false;};
  1838. break;
  1839. case "hide" : if (editorInstance.EditorWindow.parent.document.getElementById("xExpanded").style.display != "none")
  1840. {
  1841. editorInstance.EditorWindow.parent.document.getElementById("xExpanded").isHidden = true;
  1842. editorInstance.EditorWindow.parent.document.getElementById("xExpanded").style.display = "none";
  1843. }
  1844. else
  1845. {
  1846. editorInstance.EditorWindow.parent.document.getElementById("xCollapsed").style.display = "none";
  1847. }
  1848. break;
  1849. }
  1850. }
  1851. }
  1852. function enableFCKeditor(editorInstance)
  1853. {
  1854. //opacity
  1855. document.getElementById('rdescription___Frame').contentWindow.document.getElementsByTagName('html')[0].getElementsByTagName('body')[0].style.MozOpacity=1;
  1856. // enable the editArea
  1857. if (document.all)
  1858. {
  1859. editorInstance.EditorDocument.body.disabled = false;
  1860. }
  1861. else
  1862. {
  1863. editorInstance.EditorDocument.designMode = "on";
  1864. }
  1865. // enable the toolbar
  1866. switch (toolbarDisabledState)
  1867. {
  1868. case "collapse" : editorInstance.EditorWindow.parent.FCK.ToolbarSet._ChangeVisibility(false);
  1869. case "disable" : editorInstance.EditorWindow.parent.FCK.ToolbarSet.Enable();
  1870. editorInstance.EditorWindow.parent.FCKToolbarButton.prototype.RefreshState = buttonRefreshStateClone;
  1871. editorInstance.EditorWindow.parent.FCKToolbarSpecialCombo.prototype.RefreshState = specialComboRefreshStateClone;
  1872. break;
  1873. case "hide" : if (editorInstance.EditorWindow.parent.document.getElementById("xExpanded").isHidden == true)
  1874. {
  1875. editorInstance.EditorWindow.parent.document.getElementById("xExpanded").isHidden = false;
  1876. editorInstance.EditorWindow.parent.document.getElementById("xExpanded").style.display = "";
  1877. }
  1878. else
  1879. {
  1880. editorInstance.EditorWindow.parent.document.getElementById("xCollapsed").style.display = "";
  1881. }
  1882. break;
  1883. }
  1884. // set focus on editorArea
  1885. editorInstance.EditorWindow.focus();
  1886. // and update toolbarset
  1887. editorInstance.EditorWindow.parent.FCK.ToolbarSet.RefreshModeState();
  1888. }*/
  1889. var oldFCKcontent;
  1890. var FCKloaded=false;
  1891. var newRequirement=false;
  1892. function FCKeditor_OnComplete(editorInstance)
  1893. {
  1894. // Just hiding the toolbar can be done too
  1895. editorInstance.EditorWindow.parent.document.getElementById("xExpanded").style.display = "none";
  1896. //disableFCKeditor(editorInstance);
  1897. oldFCKcontent=editorInstance.GetXHTML(false);
  1898. FCKloaded=true;
  1899. editorInstance.ResetIsDirty();
  1900. if (newRequirement){
  1901. swEdit(newRequirement);
  1902. $jq("#swCancel").hide();
  1903. newRequirement=false;
  1904. }
  1905. if (document.all) {
  1906. // IE
  1907. editorInstance.EditorDocument.attachEvent("onkeydown", FCKkeyup) ;
  1908. editorInstance.Events.AttachEvent('OnBlur',FCKchange);
  1909. } else {
  1910. // other browser
  1911. editorInstance.EditorDocument.addEventListener( 'keyup', FCKkeyup, true ) ;
  1912. editorInstance.EditorDocument.addEventListener( 'blur', FCKchange, true ) ;
  1913. }
  1914. }
  1915. function FCKchange(event){
  1916. //get instance of the fckeditor
  1917. /*var editorInstance = FCKeditorAPI.GetInstance('rdescription');
  1918. if (editorInstance.IsDirty()){
  1919. editorInstance.ExecuteNamedCommand ('SelectAll');
  1920. editorInstance.InsertHtml(changeTagsGreen(editorInstance.GetXHTML(false)));
  1921. showSimilars();
  1922. editorInstance.ResetIsDirty();
  1923. }*/
  1924. }
  1925. function FCKkeyup(event){
  1926. //get instance of the fckeditor
  1927. var editorInstance = FCKeditorAPI.GetInstance('rdescription');
  1928. // load similar req on space
  1929. //IE
  1930. if (document.all){
  1931. if ((event.keyCode == 32)||(event.keyCode == 13)) {
  1932. oldText=editorInstance.GetXHTML(false);
  1933. newText=changeTagsGreen(oldText);
  1934. //the editor inserts a &nbsp; when a new paragraph is started
  1935. //this whitespace is being deleted
  1936. if (event.keyCode == 13 && newText.toLowerCase().substr(newText.length-13)=='<p>&nbsp;</p>') newText=newText.substr(0,newText.length-13)+'<p></p>';
  1937. if (newText!=oldText){
  1938. editorInstance.ExecuteNamedCommand ('SelectAll');
  1939. editorInstance.InsertHtml(newText);
  1940. }
  1941. showSimilars();
  1942. }
  1943. }
  1944. //other browsers
  1945. else{
  1946. if ((event.which == 32)||(event.which == 13)) {
  1947. showSimilars();
  1948. /* This is switched of to prevent the firefox bug that the editor lost focus
  1949. var oldText=editorInstance.GetXHTML(false);
  1950. var newText=changeTagsGreen2(oldText);
  1951. if (oldText!=newText){
  1952. editorInstance.ExecuteNamedCommand ('SelectAll');
  1953. editorInstance.InsertHtml(changeTagsGreen(editorInstance.GetXHTML(false)));
  1954. showSimilars();
  1955. $jq('#rtitle').blur();
  1956. }
  1957. */
  1958. }
  1959. }
  1960. }
  1961. var backParameter="";
  1962. function changeTagsGreen(text){
  1963. var myregex=new RegExp(/<\/font>/g);
  1964. text=text.replace(myregex,'');
  1965. myregex=new RegExp(/<font[^>]*>/g);
  1966. text=text.replace(myregex,'');
  1967. myregex=new RegExp(/&nbsp;/g);
  1968. text=text.replace(myregex,' ');
  1969. if (text.substr(text.length-5,1)==' ') text=text.substr(0,text.length-5)+'&nbsp;'+text.substr(text.length-4);
  1970. for (var i=0;i<glossaryTags.length;i++){
  1971. myregex=new RegExp('(\\W)'+glossaryTags[i]['tagName']+'(\\W)','g');
  1972. text=text.replace(myregex,'$1<font style=\"color: rgb(0, 178, 82);" title="'+glossaryTags[i]['tagComment']+'">'+glossaryTags[i]['tagName']+'</font>$2');
  1973. }
  1974. return text;
  1975. }
  1976. function changeTagsGreen2(text){
  1977. var myregex=new RegExp(/<\/font>/g);
  1978. text=text.replace(myregex,'');
  1979. myregex=new RegExp(/<font[^>]*>/g);
  1980. text=text.replace(myregex,'');
  1981. for (var i=0;i<glossaryTags.length;i++){
  1982. myregex=new RegExp('(\\W)'+glossaryTags[i]['tagName']+'(\\W)','g');
  1983. text=text.replace(myregex,'$1<font title="'+glossaryTags[i]['tagComment']+'" style="color: rgb(0, 178, 82);">'+glossaryTags[i]['tagName']+'</font>$2');
  1984. }
  1985. return text;
  1986. }