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

Last change on this file since 30382 was 30382, checked in by Georgiy Litvinov, 8 years ago

Added hierarchy menu with suggestions to metadata editor

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