source: main/trunk/greenstone3/web/interfaces/default/js/hierarchy.js@ 31064

Last change on this file since 31064 was 31064, checked in by Georgiy Litvinov, 7 years ago

Optimized regular expression in hierarchy menu

File size: 13.0 KB
Line 
1//hierarchy storage object
2
3//hierarchy menu Button text
4var hierarchyMenuButton = "Menu";
5//Find first ancestor element by tag name
6function findAncestorByTagName (element, tagName) {
7 while ((element.tagName != tagName) && (element = element.parentElement));
8 return element;
9}
10// Function to set Id as TEXTAREA value
11function chooseHierarchyOption(a)
12{
13
14 var metaValue = a.getAttribute("metavalue");
15 var metaTitle = a.getAttribute("metatitle");
16
17// If ID defined and not null
18 if (metaValue && (metaValue != null))
19 {
20 //find TR Ancestor to get TEXTAREA
21 var tr = findAncestorByTagName(a,"TR");
22 //Set value to id of clicked element
23 $(tr.getElementsByTagName("TEXTAREA")).val(metaValue);
24 // Set button name
25 setHierarchyButtonText(tr, metaTitle);
26 removeSuggestionsMenu(tr);
27 //Hide menu after click
28 $(tr).find(".metaDataHierarchyMenu").find("ul li ul li").hide();
29 //Set focus on textarea
30 tr.getElementsByTagName("TEXTAREA")[0].focus();
31
32 createSuggestionsMenu(tr);
33
34 }
35}
36function openHierarchyMenuLevel(menuItem)
37{
38 var tr = findAncestorByTagName(menuItem,"TR");
39 //get current MetaDataName
40 var metaName = getMetaName(tr);
41 //Get current hierarchy from storages
42 var hierarchyData = hierarchyStorage[metaName];
43 menuItem = $(menuItem);
44 if (menuItem.find('ul').length == 0)
45 {
46 //Expression to extract hierarchy identifier from menu item id
47 var getIdExp = /[0-9.]+/;
48 //Extracted hierarchy identifier
49 var id;
50 //Expression to get childs
51 var childExpr;
52 if (menuItem.attr('id'))
53 {
54 id = menuItem.attr('id').match(getIdExp);
55 }
56 if (id == null)
57 {
58 childExpr = /^[0-9]+$/;
59 }
60 else
61 {
62 childExpr = new RegExp("^" + id + "." + "[0-9]+$");
63 }
64 var levelItems = {};
65 for(var key in hierarchyData)
66 {
67 if(childExpr.test(key)){
68 levelItems[key]='<li class="hierarchyOption" id="'+key+'" ><button onclick="chooseHierarchyOption(this)" metavalue="'+ hierarchyData[key][0] +'" metatitle="'+ hierarchyData[key][1] +'">' + hierarchyData[key][1] + '</button></li>';
69 }
70 }
71 //If no elements in hierarchy level
72 if (jQuery.isEmptyObject(levelItems))
73 {
74 //add empty menu. Invisible. Used by checks in setHierarchyEventsWrappers focusout to prevent menu hiding while choosing suggestion menu item leaf
75 menuItem.append("<ul></ul>");
76
77 }
78 else {
79 //wrap elements in hierarchy level
80 var levelMenu = '<ul>';
81 for(var key in levelItems)
82 {
83 //Fill menu with items
84 levelMenu += levelItems[key];
85 }
86 levelMenu += "</ul>";
87 menuItem.append(levelMenu);
88 menuItem.find("li").hover(
89 function(){openHierarchyMenuLevel(this);}
90 ,
91 function(){closeHierarchyMenuLevel(this);}
92 );
93
94 //menuItem.find('ul');
95 menuItem.children('ul').slideDown();
96 }
97
98 } else {
99 //stop animation
100 menuItem.find('ul').stop(true, true);
101 //show menu items
102 menuItem.children('ul').children('li').show();
103 //slide down menu
104 menuItem.children('ul').slideDown();
105 }
106 menuItem.addClass("active");
107}
108function closeHierarchyMenuLevel(menuItem)
109{
110 $(menuItem).removeClass("active");
111 $(menuItem).find('ul').hide();
112}
113// Download hierarchy file and process it
114function downloadAndProcessHierarchyFile(hierarchyFileName,metaName)
115{
116
117 var xmlhttp=new XMLHttpRequest();
118 xmlhttp.open("GET",hierarchyFileName,true);
119 xmlhttp.send();
120 xmlhttp.onreadystatechange=function()
121 {
122 if (xmlhttp.readyState==4 && xmlhttp.status==200)
123 {
124 var hierarchyFile = xmlhttp.responseText;
125 var StringData = [];
126 var hierarchyData = {};
127 var expr = /^(\S*|\"[^\"]*\")\ +([0-9]+(?:\.[0-9]+)*)\ +(.*)/m;
128 StringData = hierarchyFile.split('\n');
129 for (var i = 0; i < StringData.length; i++) {
130 var result = StringData[i].match(expr);
131 // If result not null
132 if (result != null && result.length == 4) {
133 // populate hierarchy object
134 hierarchyData[result[2]] = [ result[1].replace(/^\"|\"$/g, ''), result[3].replace(/^\"|\"$/g, '') ];
135 }
136
137 }
138 addHierarchyToStorage(metaName, hierarchyData);
139 setHierarchyEventsWrappers(metaName);
140 }
141 }
142
143}
144
145
146function setHierarchyHoverEvent(father,className)
147{
148
149 $(father).find(className).hover(function()
150 {
151 openHierarchyMenuLevel(this);
152 }, function() {
153 closeHierarchyMenuLevel(this);
154 });
155
156}
157function createHierarchyMenuButton(row)
158{
159 //get current MetaDataName
160 var metaName = getMetaName(row);
161 defaultHierarchyButtonText = 'Top level menu';
162 var hierarchyButtonText = defaultHierarchyButtonText;
163 // Check if textarea already contain right menu key
164 var textAreaValue = $(row).find('TEXTAREA').val();
165
166 //Get current hierarchy from storages
167 var hierarchyData = hierarchyStorage[metaName];
168 //TODO Modificate
169
170
171 for(var key in hierarchyData)
172 {
173 if (hierarchyData[key][0] == textAreaValue)
174 {
175 hierarchyButtonText = hierarchyData[key][1];
176 break;
177 }
178 }
179
180 //Menu element
181 var mainmenu = '<td class="metaDataHierarchyMenu" style="display: none;"><ul><li id="hierarchyLevel"><button class="hierarchyMenuButton" title="Menu">' + hierarchyButtonText + '</button></li></ul></td>'
182 //Insert hierarchy menu
183 $(row).find('.metaTableCellRemove').after(mainmenu);
184 //Set hover event on hierarchy menu
185 $(row).each(function(){setHierarchyHoverEvent($(this),".metaDataHierarchyMenu ul li")});
186 //Set menu name or SuggestionsMenu on change of textarea set menu name to appropriate menu item if exists
187 $(row).find('.metaTableCellArea').bind('input propertychange',function()
188 {
189 var input = $(this).val();
190 var hierarchyButtonText;
191 var row = this.parentElement.parentElement;
192 //RegExp to test a valid key in input
193 var KeyExp = /^[0-9]+(?:\.[0-9]+)*$/;
194 //RegExp to test a valid key start in input
195 var KeyStartExp = /^(?:[0-9]+(?:\.[0-9]+)*)?\.$/;
196 //if input valid and key found
197 removeSuggestionsMenu(row);
198 createSuggestionsMenu(row);
199 /*if ( KeyExp.test(input) && hierarchyData[input] || KeyStartExp.test(input))
200 {
201 createSuggestionsMenu(row);
202 }
203 */
204 if (hierarchyData[input]){
205 hierarchyButtonText = hierarchyData[input][1];
206 } else {
207 hierarchyButtonText = defaultHierarchyButtonText;
208 }
209 setHierarchyButtonText(row, hierarchyButtonText);
210
211 });
212 //Show created menu
213 $(row).find('.metaDataHierarchyMenu').show();
214}
215
216function createSuggestionsMenu(row)
217{
218 //get current MetaDataName
219 var metaName = getMetaName(row);
220 //Get current hierarchy from storage
221 var hierarchyData = hierarchyStorage[metaName];
222 //Hierarchy suggestions menu
223 var SuggestionsMenu = "";
224
225 var input = $(row.getElementsByClassName("metaTableCellArea")[0]).val();
226
227 if (input.replace(/[0-9\.\s]/g, '') === "")
228 {
229 //RegExp to get SuggestionsMenu
230 var SuggestionsMenuExp = new RegExp("^0*" + input.replace(/\./g, '\\.0*') + "\\.?[0-9]+$")
231
232 for(var key in hierarchyData)
233 {
234 if (SuggestionsMenuExp.test(key))
235 {
236 SuggestionsMenu +='<li class="hierarchySuggestionsMenu hierarchyOption" id="'+key+'" ><button metavalue="'+ hierarchyData[key][0] +'" metatitle="'+ hierarchyData[key][1] +'" onclick="chooseHierarchyOption(this)" >' + key.substring(String(input).length) + " " + hierarchyData[key][1] + '</button></li>';
237 }
238 }
239 } else {
240 var escapedInput = input.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
241 //RegExp to get SuggestionsMenu
242 var SuggestionsMenuExp = new RegExp( escapedInput,"i");
243
244 for(var key in hierarchyData)
245 {
246 if (SuggestionsMenuExp.test(hierarchyData[key][1]) && input !== hierarchyData[key][0])
247 {
248 SuggestionsMenu +='<li class="hierarchySuggestionsMenu hierarchyOption" id="'+key+'" ><button metavalue="'+ hierarchyData[key][0] +'" metatitle="'+ hierarchyData[key][1] +'" onclick="chooseHierarchyOption(this)" >' + hierarchyData[key][1] + '</button></li>';
249 }
250 }
251 }
252
253
254
255 //Append new SuggestionsMenu
256 $(row).find(".metaDataHierarchyMenu ul").append(SuggestionsMenu);
257 //Register event
258 $(row).each(function(){setHierarchyHoverEvent($(this),".hierarchySuggestionsMenu")});
259}
260//function removeSuggestionsMenu(row,menuNewText)
261function removeSuggestionsMenu(row)
262{
263 $(row).find(".hierarchySuggestionsMenu").remove();
264}
265function setHierarchyButtonText(row, title){
266 $(row).find(".hierarchyMenuButton").text(title);
267}
268
269function setHierarchyEventsWrappers(metaName)
270{
271 //Loop through every metaTableCell
272 $(".metaTableCellName").each(function() {
273 //Check if it is a hierarchy row
274 var currentMetaName = $(this).text();
275 if (currentMetaName in hierarchyStorage && currentMetaName == metaName)
276 {
277 var row = this.parentElement;
278 var textArea = row.getElementsByClassName("metaTableCellArea")[0];
279
280 //Mouse leave row
281 $(row).mouseleave(function() {
282 //textArea = this.getElementsByClassName("metaTableCellArea")[0];
283 if (this.getElementsByClassName("metaDataHierarchyMenu").length != 0 && document.activeElement.tagName != "TEXTAREA")
284 {
285 $(this).find('ul').stop(true, true);
286 //Remove hierarchy menu
287 $(this).find('.metaDataHierarchyMenu').hide();
288 }
289
290 });
291 // Mouse enter row
292 $(row).mouseenter(
293 function()
294 {
295 var row = this;
296 var table = row.parentElement;
297 //If focused on TEXTAREA do nothing
298 if (document.activeElement.tagName != "TEXTAREA")
299 {
300 //Hide all menus in table except this one
301 $(table).find('.metaDataHierarchyMenu').each(function() {
302 var currentRow = this.parentElement;
303 if (!$(currentRow).is($(row)) )
304 {
305 $(this).hide();
306 }
307 });
308
309 // createHierarchyMenuButton($(row));
310 if ( $(row).find('ul').length == 0 )
311 {
312 createHierarchyMenuButton(row);
313 createSuggestionsMenu(row);
314 }
315 else
316 {
317 //Unhide menu
318 $(row).find('.metaDataHierarchyMenu').show();
319 //Minimize nested menus
320 $(row).find('.metaDataHierarchyMenu ul').find('ul').hide();
321 }
322 }
323
324
325 }
326 );
327
328
329 // Textarea focus
330 $(textArea).focus(
331 function()
332 {
333 var row = this.parentElement.parentElement;
334 var table = row.parentElement;
335
336
337 //Hide all menus in table except this one
338 $(table).find('.metaDataHierarchyMenu').each(function() {
339 var currentRow = this.parentElement;
340 if (!$(currentRow).is($(row)) )
341 {
342 $(this).hide();
343 }
344 });
345 //Create button
346 if ( $(row).find('ul').length == 0 )
347 {
348 createHierarchyMenuButton(row);
349 createSuggestionsMenu(row);
350 }
351 else
352 {
353 //Unhide menu
354 $(row).find('.metaDataHierarchyMenu').show();
355 //Minimize nested menus
356 $(row).find('.metaDataHierarchyMenu ul').find('ul').slideUp();
357 }
358
359
360 }
361 );
362 $(textArea).focusout(
363 function()
364 {
365 var row = this.parentElement.parentElement;
366
367 var found = $(row).find('.metaDataHierarchyMenu ul li ul').filter(":visible")[0];
368 //Test if there are open submenu and cursor left tr element
369 if ( found === undefined && !$(row).is(':hover'))
370 {
371 //Hide hierarchy menu if there are no open submenus
372 $(row).find('.metaDataHierarchyMenu').hide();
373
374 //Set metadata value if textarea contains hierarchy path
375 substituteHierarchyMetaValue(row);
376 }
377
378
379 }
380 );
381 }
382 });
383}
384
385function substituteHierarchyMetaValue(row){
386 var text = $(row).find('TEXTAREA').val();
387 var metaName = getMetaName(row);
388 var hierarchyData = hierarchyStorage[metaName];
389 if (hierarchyData[text]){
390 var metaValue = hierarchyData[text][0];
391 $(row).find('TEXTAREA').val(metaValue);
392
393 }
394
395}
396function getMetaName(row){
397 return $(row.getElementsByClassName("metaTableCellName")[0]).text();
398}
399var hierarchyStorage = {};
400function addHierarchyToStorage(metaDataName,processedHierarchy)
401{
402 hierarchyStorage[metaDataName] = processedHierarchy;
403
404}
405
Note: See TracBrowser for help on using the repository browser.