changeset 55:95bf4ac726e6

Topic synchronization with extraction-interface. new tables in LGService database
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Tue, 16 Feb 2016 15:09:40 +0100
parents a00efd5d9e77
children dd8348304dba
files src/main/java/de/mpiwg/gazetteer/bo/DBEntry.java src/main/java/de/mpiwg/gazetteer/bo/LGTopic.java src/main/java/de/mpiwg/gazetteer/utils/DBService.java src/main/java/de/mpiwg/gazetteer/utils/DataProvider.java src/main/java/de/mpiwg/web/jsp/FullTextSearchPage.java src/main/java/de/mpiwg/web/jsp/TopicListPage.java src/main/resources/hibernate.cfg.xml src/main/webapp/componentes/template.jsp src/main/webapp/pages/fullTextSearch.jsp src/main/webapp/pages/topicList.jsp src/main/webapp/pages/topicPage.jsp src/main/webapp/resources/css/style.css src/main/webapp/resources/js/general.js
diffstat 13 files changed, 294 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/de/mpiwg/gazetteer/bo/DBEntry.java	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/java/de/mpiwg/gazetteer/bo/DBEntry.java	Tue Feb 16 15:09:40 2016 +0100
@@ -13,6 +13,8 @@
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 
+import org.hibernate.annotations.GenericGenerator;
+
 @Entity
 @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
 public abstract class DBEntry {
@@ -22,7 +24,7 @@
 	public DBEntry(){}
 	
 	@Id
-    @GeneratedValue(strategy = GenerationType.TABLE)
+	@GeneratedValue(strategy = GenerationType.TABLE)
     @Column(name="id")
     protected Long id;
 	
--- a/src/main/java/de/mpiwg/gazetteer/bo/LGTopic.java	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/java/de/mpiwg/gazetteer/bo/LGTopic.java	Tue Feb 16 15:09:40 2016 +0100
@@ -49,6 +49,10 @@
 	@Column(name="keywords")
 	private String keywords;
 
+	@Column(name="tag")
+	private String tag;
+
+	
 	
 	@Transient
 	private List<Long> contributorsList;
@@ -219,6 +223,17 @@
 	}
 
 
+	public String getTag() {
+		return tag;
+	}
+
+
+	public void setTag(String tag) {
+		this.tag = tag;
+	}
+
+
+
 	public void setContributorsList(List<Long> contributorsList) {
 		this.contributorsList = contributorsList;
 	}
@@ -232,7 +247,7 @@
 	
 	public Integer getNumOfSections() {
 		if (numOfSections == 0){
-			// TODO get number of sections in this topic from db table TopicSectionRelation with topicId=this.topicId
+			// get number of sections in this topic from db table TopicSectionRelation with topicId=this.topicId
 			Long topicId = this.getId();
 			
 			this.setNumOfSections(DataProvider.getInstance().getNumberOfSectionInTopic(topicId));
--- a/src/main/java/de/mpiwg/gazetteer/utils/DBService.java	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/java/de/mpiwg/gazetteer/utils/DBService.java	Tue Feb 16 15:09:40 2016 +0100
@@ -976,6 +976,7 @@
 		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 		session.getTransaction().begin();
 		
+		// delete record in Topic table
 		Query query = session.createQuery("delete LGTopic where id = :id");
 		query.setLong("id", topicId);
 		modifiedTopic = query.executeUpdate();
@@ -986,6 +987,12 @@
 		query0.setLong("topicId", topicId);
 		modifiedTopic += query0.executeUpdate();
 		
+		// delete records in TopicTagRelation table
+		Query query1 = session.createQuery("delete LGTopicTagRelation where topicId = :topicId");
+		query1.setLong("topicId", topicId);
+		modifiedTopic += query1.executeUpdate();
+		
+		
 		session.getTransaction().commit();
 		
 		return modifiedTopic;
--- a/src/main/java/de/mpiwg/gazetteer/utils/DataProvider.java	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/java/de/mpiwg/gazetteer/utils/DataProvider.java	Tue Feb 16 15:09:40 2016 +0100
@@ -14,8 +14,10 @@
 import de.mpiwg.gazetteer.bo.LGBranch;
 import de.mpiwg.gazetteer.bo.LGFile;
 import de.mpiwg.gazetteer.bo.LGFullTextSearchFile;
+import de.mpiwg.gazetteer.bo.LGTaglist;
 import de.mpiwg.gazetteer.bo.LGTopic;
 import de.mpiwg.gazetteer.bo.LGTopicSectionRelation;
+import de.mpiwg.gazetteer.bo.LGTopicTagRelation;
 import de.mpiwg.gazetteer.db.DBContents;
 import de.mpiwg.gazetteer.db.DBSection;
 import de.mpiwg.gazetteer.utils.exceptions.NoAuthorizedException;
@@ -372,11 +374,10 @@
 		int modifiedRelation = DBService.deleteTopicFromDB(topic.getId());
 		getTopicMap().remove(topic.getKey());
 		
-		logger.info("removing " + modifiedRelation + " records in topicSectionRelation of topic " + topic.toString());
+		logger.info("removing " + modifiedRelation + " records in TopicSectionRelation and TopicTagRelation table for the topic " + topic.toString());
 		
 		this.setTopicSectionRelationMap(null);	// clear topicSectionRelationMap cache
 		
-
 	}
 
 	public void createTopic(String nameEn, String nameCh,String namePinyin, String description, Long userId) {
@@ -390,6 +391,11 @@
 		topic.setUserId(userId);
 		topic.setContributors("[" + userId.toString() + "]");
 		
+		// auto-generating a tag for the topic: could be from nameEn replace space with '_'
+		String tag = new String();
+		tag = nameEn.replace(' ', '_');
+		topic.setTag(tag);
+		
 		//Saving into DB
 		//##################################
 		// For Topic table
@@ -398,6 +404,30 @@
 		
 		DBService.saveDBEntry0(session, topic, date);
 			
+		// For Taglist table
+		// create record, which is the topic tag, in taglist table,
+		// with the taglis.name=nameCh, the taglist.tag=tag, the taglist.color=the defualt topic tag color, which is rgb(255,0,174)
+		
+		LGTaglist taglist = new LGTaglist();
+		taglist.setName(nameCh);
+		taglist.setTag(tag);
+		taglist.setColor("rgb(255, 0, 174)");
+		
+		DBService.saveDBEntry0(session, taglist, date);
+		
+		
+		logger.debug("new topic tag id=" + taglist.getId());
+		
+		
+		// For TopicTagRelation table
+		// link the relation between the new topic and its corresponding tag
+		LGTopicTagRelation relation = new LGTopicTagRelation();
+		relation.setTagId(taglist.getId());
+		relation.setTopicId(topic.getId());
+		
+		DBService.saveDBEntry0(session, relation, date);
+		
+		
 		session.getTransaction().commit();
 		//##################################
 		
--- a/src/main/java/de/mpiwg/web/jsp/FullTextSearchPage.java	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/java/de/mpiwg/web/jsp/FullTextSearchPage.java	Tue Feb 16 15:09:40 2016 +0100
@@ -3,6 +3,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
@@ -68,6 +69,11 @@
 	private String contentFilter = new String();
 	
 	private List<LGFullTextSearchFile> fileList = null;
+	private List<LGFullTextSearchFile> weekFileList = null;	// files modified within the past week
+	private List<LGFullTextSearchFile> monthFileList = null;	// files modified within the past month
+	private List<LGFullTextSearchFile> olderFileList = null;	// files modified before one month ago
+	
+	
 	private String fileName = new String();
 	
 	private String focusedContentId = new String();
@@ -206,6 +212,36 @@
 		this.setSelectedContentMessage(this.selectedNumOfContent.toString() + " section(s) selected");
 	}
 
+	
+	private void dispatchFileListByTime() {
+		// set this.weekFileList, this.monthFileList, this.olderFileList from this.fileList
+		this.weekFileList = new ArrayList<LGFullTextSearchFile>();
+		this.monthFileList = new ArrayList<LGFullTextSearchFile>();
+		this.olderFileList = new ArrayList<LGFullTextSearchFile>();
+		
+	
+		// TODO
+		for (LGFullTextSearchFile aFile: this.getFileList()) {
+			Date todayDate = new Date();
+			
+			long DAY_IN_MS = 1000 * 60 * 60 * 24;
+			Date oneWeekAgo = new Date(todayDate.getTime() - (7 * DAY_IN_MS));
+			Date oneMonthAgo = new Date(todayDate.getTime() - (30 * DAY_IN_MS));
+			
+			if ( aFile.getLastChangeDate().after(oneWeekAgo)) {
+				this.weekFileList.add(aFile);
+				
+			} else if (aFile.getLastChangeDate().after(oneMonthAgo)) {
+				this.monthFileList.add(aFile);
+				
+			} else {
+				this.olderFileList.add(aFile);
+			}
+		
+		}
+		
+	}
+	
 	public void forceLoadFileList(){
 		logger.debug("forceLoadFileList");
 		logger.debug(this.getSearchTerm());
@@ -214,12 +250,19 @@
 			//logger.debug("userId="+ getSessionBean().getUser().getId());
 			
 			// set FileList for the user
-			DataProvider.getInstance().setFullTextSearchFileMap(null);	// set fullTextSearchFileMap to null, to force reload
-			this.setFileList(DataProvider.getInstance().getSearchFileList4User(getSessionBean().getUser().getId()));				
+			this.forceSetFileLists();
+			
 		}
 
 	}
 	
+	private void forceSetFileLists() {
+		// set FileList for the user
+		DataProvider.getInstance().setFullTextSearchFileMap(null);	// set fullTextSearchFileMap to null, to force reload
+		this.setFileList(DataProvider.getInstance().getSearchFileList4User(getSessionBean().getUser().getId()));	
+		this.dispatchFileListByTime();
+	}
+	
 	public void deleteFile() throws IOException {
 		
 		Long fileId = getLongParameter("fileId");
@@ -233,8 +276,7 @@
 				DataProvider.getInstance().deleteLGFullTextSearchFile(file);
 				
 				// update FileList
-				DataProvider.getInstance().setFullTextSearchFileMap(null);	// set fullTextSearchFileMap to null, to force reload
-				this.setFileList(DataProvider.getInstance().getSearchFileList4User(getSessionBean().getUser().getId()));
+				this.forceSetFileLists();
 				
 				addMsg("The file " + file.getFileName() + " has been deleted.");
 			}	
@@ -385,9 +427,7 @@
 			internalError(e);
 		}
 		
-		// update FileList
-		DataProvider.getInstance().setFullTextSearchFileMap(null);	// set fullTextSearchFileMap to null, to force reload
-		this.setFileList(DataProvider.getInstance().getSearchFileList4User(getSessionBean().getUser().getId()));
+		this.forceSetFileLists();
 		
 	}
 	
@@ -777,6 +817,30 @@
 
 
 
+	public List<LGFullTextSearchFile> getWeekFileList() {
+		return weekFileList;
+	}
+
+	public void setWeekFileList(List<LGFullTextSearchFile> weekFileList) {
+		this.weekFileList = weekFileList;
+	}
+
+	public List<LGFullTextSearchFile> getMonthFileList() {
+		return monthFileList;
+	}
+
+	public void setMonthFileList(List<LGFullTextSearchFile> monthFileList) {
+		this.monthFileList = monthFileList;
+	}
+
+	public List<LGFullTextSearchFile> getOlderFileList() {
+		return olderFileList;
+	}
+
+	public void setOlderFileList(List<LGFullTextSearchFile> olderFileList) {
+		this.olderFileList = olderFileList;
+	}
+
 	public String getMouseX() {
 		return mouseX;
 	}
--- a/src/main/java/de/mpiwg/web/jsp/TopicListPage.java	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/java/de/mpiwg/web/jsp/TopicListPage.java	Tue Feb 16 15:09:40 2016 +0100
@@ -93,10 +93,9 @@
 			addMsg("Creating topic Failed. Name(Eng) cannot be empty.");
 		} else if (StringUtils.isEmpty(nameCh)) {
 			addMsg("Creating topic Failed. Name(中文) cannot be empty.");
-		}else if (StringUtils.isEmpty(namePinyin)) {
+		} else if (StringUtils.isEmpty(namePinyin)) {
 			addMsg("Creating topic Failed. Name(Pinyin) cannot be empty.");
 		} else {
-			
 			DataProvider.getInstance().createTopic(nameEn, nameCh, namePinyin, description, userId);
 			
 			addMsg("New topic has been created.");			
--- a/src/main/resources/hibernate.cfg.xml	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/resources/hibernate.cfg.xml	Tue Feb 16 15:09:40 2016 +0100
@@ -39,8 +39,10 @@
 		<mapping class="de.mpiwg.gazetteer.bo.LGFullTextSearchFile"/>
 		<mapping class="de.mpiwg.gazetteer.bo.Sequence"/>	  
 		<mapping class="de.mpiwg.gazetteer.bo.LGTopic"/>
+		<mapping class="de.mpiwg.gazetteer.bo.LGTaglist"/>
 		<mapping class="de.mpiwg.gazetteer.bo.LGTopicSectionRelation"/>
-	    	    
+	  	<mapping class="de.mpiwg.gazetteer.bo.LGTopicTagRelation"/>
+			    
 	</session-factory>
 
 </hibernate-configuration>
--- a/src/main/webapp/componentes/template.jsp	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/webapp/componentes/template.jsp	Tue Feb 16 15:09:40 2016 +0100
@@ -45,7 +45,7 @@
 			<% if(sessionBean.getUser() == null) { %>
 			<table>
 				<tr>
-					<td><a href="<%=sessionBean.getApplicationBean().getDvnRootServer() %>/faces/login/AddAccountPage.xhtml"target="_blank" style="font-size: 12px;">Create Account</a></td>
+					<td><a href="<%=sessionBean.getApplicationBean().getDvnRootServer() %>/dataverseuser.xhtml?editMode=CREATE" target="_blank" style="font-size: 12px;">Create Account</a></td>
 					<td><label>Login</label></td>
 					<td><input type="text" name="userName"/></td>
 					<td><input type="password" name="password" /></td>
--- a/src/main/webapp/pages/fullTextSearch.jsp	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/webapp/pages/fullTextSearch.jsp	Tue Feb 16 15:09:40 2016 +0100
@@ -49,10 +49,10 @@
 			var dialogViewSavedResult = $("#dialogViewSavedResult").dialog(
 				{
 					autoOpen: false,
-					position: { my: "left+100px", at: "top", of: $("#viewSavedResult") },
+					//position: { my: "left+100px", at: "top", of: $("#viewSavedResult") },
+					position: { my: "center", at: "top+200px", of: $("#viewSavedResult") },	// TODO
+					width: "850px",
 
-					//position: { my: "center", at: "top+150px", of: $("#viewSavedResult") },	// TODO
-					// width: "600px",
 				}
 		  	);
 			$("#viewSavedResult").button().on( "click", function() {
@@ -177,44 +177,104 @@
 			 	
 			</div>	
 			
-			<div id="dialogViewSavedResult" title="Saved Table">
+			<div id="dialogViewSavedResult" title="Saved Table(s)">
 				
-				<div class="label">Recent</div>		
-				<table class="pageTable">
+				<div class="label">This week:</div>		
+				<table class="savedResultTable">
+				<tr>
+					<% for (LGFullTextSearchFile aFile : sessionBean.getFullTextSearchPage().getWeekFileList() ){%>
+					<td>
+						<div><%= aFile.getFileName() %></div>
+						<button type="button" class="lgButton" onclick="setAction0('loadFile', 'fullTextSearchForm', 'fileId', <%=aFile.getId() %>); document.getElementById('fullTextSearchForm').submit();">load</button>	
+					
+						<!-- getFullTextSearchFileText?fileId= &userId= -->
 				
-					<% for (LGFullTextSearchFile aFile : sessionBean.getFullTextSearchPage().getFileList() ){%>
-					<tr><td>
-						<%= aFile.getFileName() %>
-						
-							<button type="button" class="lgButton" onclick="setAction0('loadFile', 'fullTextSearchForm', 'fileId', <%=aFile.getId() %>); document.getElementById('fullTextSearchForm').submit();">load</button>	
-						
-							<!-- getFullTextSearchFileText?fileId= &userId= -->
+						<!-- click searching result to open it in the same table of full-text-search result -->
+						<a href="<%=sessionBean.getApplicationBean().getRootServer() %>/rest/text/getFullTextSearchHtmlFile?fileId=<%= aFile.getId() %>"
+									target="_blank">
+							<img title="Show text in html" src="<%=sessionBean.getApplicationBean().getShowImage()%>"/>	
+						</a>
+						<!-- view on LGMap -->
+						<a href="<%=sessionBean.getApplicationBean().getLGMapUrl() %>&file=<%=aFile.getUserId().toString()%>_<%=aFile.getFileName()%>.csv&name=<%=aFile.getSearchTerms() %>"
+									target="_blank">
+							<img title="View on LGMap" src="<%=sessionBean.getApplicationBean().getViewOnMap()%>"/>	
+						</a>
+					
+						<input type="image" title="Delete it"
+							onclick="<%=sessionBean.getApplicationBean().getJSConfirmationDelete() %> setAction0('deleteFile', 'fullTextSearchForm', 'fileId','<%=aFile.getId() %>'); document.getElementById('fullTextSearchForm').submit();" 
+							src="<%=sessionBean.getApplicationBean().getDeleteImage()%>"/>
+					
+					</td>
 					
-							<!-- click searching result to open it in the same table of full-text-search result -->
-							<a href="<%=sessionBean.getApplicationBean().getRootServer() %>/rest/text/getFullTextSearchHtmlFile?fileId=<%= aFile.getId() %>"
-										target="_blank">
-								<img title="Show text in html" src="<%=sessionBean.getApplicationBean().getShowImage()%>"/>	
-							</a>
-						
+					<% } %>
+					</tr>
+				</table>
+			
+				<div class="label">This month:</div>		
+				<table class="savedResultTable">
+				<tr>
+					<% for (LGFullTextSearchFile aFile : sessionBean.getFullTextSearchPage().getMonthFileList() ){ %>				
+					<td>
+						<div><%= aFile.getFileName() %></div>
+						<button type="button" class="lgButton" onclick="setAction0('loadFile', 'fullTextSearchForm', 'fileId', <%=aFile.getId() %>); document.getElementById('fullTextSearchForm').submit();">load</button>	
+					
+						<!-- getFullTextSearchFileText?fileId= &userId= -->
 				
-							<!-- view on LGMap -->
-							<a href="<%=sessionBean.getApplicationBean().getLGMapUrl() %>&file=<%=aFile.getUserId().toString()%>_<%=aFile.getFileName()%>.csv&name=<%=aFile.getSearchTerms() %>"
-										target="_blank">
-								<img title="View on LGMap" src="<%=sessionBean.getApplicationBean().getViewOnMap()%>"/>	
-							</a>
+						<!-- click searching result to open it in the same table of full-text-search result -->
+						<a href="<%=sessionBean.getApplicationBean().getRootServer() %>/rest/text/getFullTextSearchHtmlFile?fileId=<%= aFile.getId() %>"
+									target="_blank">
+							<img title="Show text in html" src="<%=sessionBean.getApplicationBean().getShowImage()%>"/>	
+						</a>
+					
+			
+						<!-- view on LGMap -->
+						<a href="<%=sessionBean.getApplicationBean().getLGMapUrl() %>&file=<%=aFile.getUserId().toString()%>_<%=aFile.getFileName()%>.csv&name=<%=aFile.getSearchTerms() %>"
+									target="_blank">
+							<img title="View on LGMap" src="<%=sessionBean.getApplicationBean().getViewOnMap()%>"/>	
+						</a>
+					
+						<input type="image" title="Delete it"
+							onclick="<%=sessionBean.getApplicationBean().getJSConfirmationDelete() %> setAction0('deleteFile', 'fullTextSearchForm', 'fileId','<%=aFile.getId() %>'); document.getElementById('fullTextSearchForm').submit();" 
+							src="<%=sessionBean.getApplicationBean().getDeleteImage()%>"/>
 						
-							<input type="image" title="Delete it"
-								onclick="<%=sessionBean.getApplicationBean().getJSConfirmationDelete() %> setAction0('deleteFile', 'fullTextSearchForm', 'fileId','<%=aFile.getId() %>'); document.getElementById('fullTextSearchForm').submit();" 
-								src="<%=sessionBean.getApplicationBean().getDeleteImage()%>"/>
-						</td>
-					<tr>
+					</td>
+					
 					<% } %>
 					</tr>
 				</table>
 				
-				<div class="label">Last Week</div>				
-				<div class="label">Last Month</div>
 				<div class="label">Older...</div>
+				<table class="savedResultTable">
+				<tr>
+					<% for (LGFullTextSearchFile aFile : sessionBean.getFullTextSearchPage().getOlderFileList() ){%>
+					<td>
+						<div><%= aFile.getFileName() %></div>
+						<button type="button" class="lgButton" onclick="setAction0('loadFile', 'fullTextSearchForm', 'fileId', <%=aFile.getId() %>); document.getElementById('fullTextSearchForm').submit();">load</button>	
+					
+						<!-- getFullTextSearchFileText?fileId= &userId= -->
+				
+						<!-- click searching result to open it in the same table of full-text-search result -->
+						<a href="<%=sessionBean.getApplicationBean().getRootServer() %>/rest/text/getFullTextSearchHtmlFile?fileId=<%= aFile.getId() %>"
+									target="_blank">
+							<img title="Show text in html" src="<%=sessionBean.getApplicationBean().getShowImage()%>"/>	
+						</a>
+					
+			
+						<!-- view on LGMap -->
+						<a href="<%=sessionBean.getApplicationBean().getLGMapUrl() %>&file=<%=aFile.getUserId().toString()%>_<%=aFile.getFileName()%>.csv&name=<%=aFile.getSearchTerms() %>"
+									target="_blank">
+							<img title="View on LGMap" src="<%=sessionBean.getApplicationBean().getViewOnMap()%>"/>	
+						</a>
+					
+						<input type="image" title="Delete it"
+							onclick="<%=sessionBean.getApplicationBean().getJSConfirmationDelete() %> setAction0('deleteFile', 'fullTextSearchForm', 'fileId','<%=aFile.getId() %>'); document.getElementById('fullTextSearchForm').submit();" 
+							src="<%=sessionBean.getApplicationBean().getDeleteImage()%>"/>
+						
+					</td>
+					
+					<% } %>
+					</tr>
+				</table>
 				
 				<!-- 
 				<table class="pageTable">
@@ -263,8 +323,6 @@
 		
 			</div>	
 		<label class="subTitel">Full Text Search</label> 
-
-			
 			<form name="fullTextSearchForm" id="fullTextSearchForm"
 				action="<%=sessionBean.getApplicationBean().getRootServer()%>/proxy.jsp"
 				method="post"
@@ -275,7 +333,6 @@
 				<input id="mouseX" name="mouseX" type="hidden" value="<%=sessionBean.getFullTextSearchPage().getMouseX() %>"/>
 				<input id="mouseY" name="mouseY" type="hidden" value="<%=sessionBean.getFullTextSearchPage().getMouseY() %>"/>
 				
-				
 				<table style="width: 300px; margin-left: auto;margin-right: auto;">
 				<tr>
 					<td>
--- a/src/main/webapp/pages/topicList.jsp	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/webapp/pages/topicList.jsp	Tue Feb 16 15:09:40 2016 +0100
@@ -11,15 +11,47 @@
 	<script>
 		$(function() {
 			var dialogCreateTopic = $("#dialogCreateTopic").dialog(
-					{autoOpen: false}
+				{
+					autoOpen: false,
+					width: "400px",		
+				}
 		  	);	  
+			
 			$("#createTopic").button().on( "click", function() {
 				dialogCreateTopic.dialog( "open" );
 			});
 			
+			$("#nameEn").on( "keydown", function( event ) {
+				
+				var englishAlphabetAndWhiteSpace =/[A-Za-z 0-9]/g;
+				
+				var key = String.fromCharCode(event.which);
+				
+				// --- key code: ---
+				// space: 32, delete: 8, enter: 13, tab: 9
+				// [a-z]: 65-91
+				// [0-9]: 48-57
+				// esc: 27
+				// shift, ctr, alt: 16, 17, 18, 20
+				// cmd: 91
+				
+				
+				if (event.keyCode == 8 || event.keyCode == 9 || (event.keyCode >= 16 && event.keyCode <= 20) || event.keyCode == 27 || event.keyCode == 37 || event.keyCode == 39 || event.keyCode == 91 || englishAlphabetAndWhiteSpace.test(key)) { 
+					return true; 
+				} 
+			
+				alert("Please type in English characters.");
+				
+				// TODO: maybe delete those chars that are not Latin char, instead of delete them all
+				$("#nameEn").val("");
+				
+				return false;
+			});
+			
 			
 		});
 		
+		
 	</script>
 </head>
 
--- a/src/main/webapp/pages/topicPage.jsp	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/webapp/pages/topicPage.jsp	Tue Feb 16 15:09:40 2016 +0100
@@ -218,7 +218,7 @@
 										<th><label class="tableTitle">Remove</label></th>
 									</tr>	
 									
-									<!-- TODO pending book list -->
+									<!-- pending book list -->
 									<% for(DBBook book : sessionBean.getTopicPage().getPendingBookList() ) { %>
 									<tr>
 										<td>
@@ -559,9 +559,10 @@
 								
 									<!-- view text in Ext-Interface -->
 									<td>
+										<!-- pass topicId to extraction interface -->
 										<a	href="#"
 											title="Show Section in Extraction Interface" 
-										 	onclick="sectionInExtractionInterface('<%=section.getId() %>', '<%=section.getName() %>', '<%=section.getBookId() %>', '<%=section.getBook().getName() %>', '<%=sessionBean.getUser().getId() %>', '<%=sessionBean.getApplicationBean().getExtractionInterfaceUrl()%>');">
+										 	onclick="sectionInExtractionInterface('<%=section.getId() %>', '<%=section.getName() %>', '<%=section.getBookId() %>', '<%=section.getBook().getName() %>', '<%=sessionBean.getTopicPage().getTopicId() %>', '<%=sessionBean.getUser().getId() %>', '<%=sessionBean.getApplicationBean().getExtractionInterfaceUrl()%>');">
 										 	<img title="Show Section in Extraction Interface" src="<%=sessionBean.getApplicationBean().getShowImage()%>">
 										</a>
 									</td>
--- a/src/main/webapp/resources/css/style.css	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/webapp/resources/css/style.css	Tue Feb 16 15:09:40 2016 +0100
@@ -134,13 +134,35 @@
 	width: 100%;
 	overflow: scroll;
 	overflow-y: hidden;
-	
 	margin-left: auto;
 	margin-right: auto;
 	border: 3px inset #ABABCC;
 	box-sizing: border-box;
 }
 
+
+.savedResultTable {
+	background-color: white;
+	border-collapse: collapse;
+}
+
+.savedResultTable tr {
+  background:#EBEBEB;
+}
+
+.savedResultTable td {
+	border-color: inherit;
+    border-style: solid;
+    border-width: 1px;
+    text-align: center;
+    border-collapse: collapse;
+    font-size: 12px;
+	min-width: 60px;
+	width:60px;
+}
+
+
+
 .pageTable{
 	width: 100%; 
 	background-color: white;
--- a/src/main/webapp/resources/js/general.js	Thu Feb 04 11:30:46 2016 +0100
+++ b/src/main/webapp/resources/js/general.js	Tue Feb 16 15:09:40 2016 +0100
@@ -6,6 +6,8 @@
 		bookName, 
 		userId, extractionInterfaceUrl){
 	
+	// the input parameters contain fileId, since a branch means a text/many version of the text, of a section
+		
 	var form = document.createElement("form");
 	form.setAttribute("method", "post");
 	form.setAttribute("action", extractionInterfaceUrl + "/Extractapp/TaggingText");  // hand to controller
@@ -57,7 +59,9 @@
 	   }
 }
 
-function sectionInExtractionInterface(sectionId, sectionName, bookId, bookName, userId, extractionInterfaceUrl){
+function sectionInExtractionInterface(sectionId, sectionName, bookId, bookName, topicId, userId, extractionInterfaceUrl){
+	
+	// the input parameters contain no fileId, since it's from searching result and haven't assigned topic Or saved
 	
 	var form = document.createElement("form");
 	form.setAttribute("method", "post");
@@ -89,6 +93,11 @@
 	hiddenField6.setAttribute("value", bookName);
 	form.appendChild(hiddenField6);	
 	
+	var hiddenField7 = document.createElement("input");      
+	hiddenField7.setAttribute("name", "topic");
+	hiddenField7.setAttribute("value", topicId);
+	form.appendChild(hiddenField7);	
+	
 	if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
 	       document.body.appendChild(form);
 	       form.submit();