Mobile Browser/iPhone App friendly demo
authorDennis Schafroth <dennis@indexdata.com>
Wed, 2 Jun 2010 12:02:03 +0000 (14:02 +0200)
committerDennis Schafroth <dennis@indexdata.com>
Wed, 2 Jun 2010 12:02:03 +0000 (14:02 +0200)
A solution for smaller screens. Using tabs to (filter) select facets.

The JavaScript also supports an iPhone Application mode
where some of the UI is hidden, as this is being done in the Application.

www/iphone/example_client.js
www/iphone/index.html
www/iphone/iphone.js [new file with mode: 0644]

index fd9c37e..b728f95 100644 (file)
@@ -18,10 +18,10 @@ my_paz = new pz2( { "onshow": my_onshow,
                     "pazpar2path": pazpar2path,
                     "oninit": my_oninit,
                     "onstat": my_onstat,
-                    "onterm": my_onterm,
+                    "onterm": my_onterm_iphone,
                     "termlist": "xtargets,subject,author",
                     "onbytarget": my_onbytarget,
-                   "usesessions" : usesessions,
+                           "usesessions" : usesessions,
                     "showResponseType": showResponseType,
                     "onrecord": my_onrecord } );
 // some state vars
@@ -36,6 +36,9 @@ var submitted = false;
 var SourceMax = 16;
 var SubjectMax = 10;
 var AuthorMax = 10;
+var tab = "recordview"; 
+var inApp = false;
+
 
 //
 // pz2.js event handlers:
@@ -61,16 +64,16 @@ function my_onshow(data) {
     var html = [];
     for (var i = 0; i < data.hits.length; i++) {
         var hit = data.hits[i];
-             html.push('<div class="record" id="recdiv_'+hit.recid+'" >'
-            +'<span>'+ (i + 1 + recPerPage * (curPage - 1)) +'. </span>'
+             html.push('<li id="recdiv_'+hit.recid+'" >'
+           /* +'<span>'+ (i + 1 + recPerPage * (curPage - 1)) +'. </span>' */
             +'<a href="#" id="rec_'+hit.recid
-            +'" onclick="showDetails(this.id);return false;"><b>' 
-            + hit["md-title"] +' </b></a>'); 
-             if (hit["md-title-remainder"] !== undefined) {
-               html.push('<span>' + hit["md-title-remainder"] + ' </span>');
-             }
+            +'" onclick="showDetails(this.id);return false;">' 
+            + hit["md-title"] +'</a> '); 
              if (hit["md-title-responsibility"] !== undefined) {
-           html.push('<span><i>'+hit["md-title-responsibility"]+'</i></span>');
+           html.push('<a href="#">'+hit["md-title-responsibility"]+'</a> ');
+             if (hit["md-title-remainder"] !== undefined) {
+               html.push('<a href="#">' + hit["md-title-remainder"] + ' </a> ');
+             }
        }
         if (hit.recid == curDetRecId) {
             html.push(renderDetails(curDetRecData));
@@ -92,22 +95,64 @@ function my_onstat(data) {
                         + '/' + data.hits + ' :.</span>';
 }
 
+function showhide(newtab) {
+       var showtermlist = false;
+       if (newtab != null)
+               tab = newtab;
+
+       if (tab == "recordview") {
+               document.getElementById("recordview").style.display = '';
+       }
+       else 
+               document.getElementById("recordview").style.display = 'none';
+
+       if (tab == "xtargets") {
+               document.getElementById("term_xtargets").style.display = '';
+               showtermlist = true;
+       }
+       else
+               document.getElementById("term_xtargets").style.display = 'none';
+       if (tab == "subjects") {
+               document.getElementById("term_subjects").style.display = '';
+               showtermlist = true;
+       }
+       else
+               document.getElementById("term_subjects").style.display = 'none';
+       if (tab == "authors") {
+               document.getElementById("term_authors").style.display = '';
+               showtermlist = true;
+       }
+       else
+               document.getElementById("term_authors").style.display = 'none';
+
+       if (showtermlist == false) 
+               document.getElementById("termlist").style.display = 'none';
+       else 
+               document.getElementById("termlist").style.display = '';
+}
+
 function my_onterm(data) {
     var termlists = [];
-    termlists.push('<hr/><b>TERMLISTS:</b><hr/><div class="termtitle">.::Sources</div>');
+    
+    termlists.push('<div id="term_xtargets" >');
+    termlists.push('<div class="termtitle">.::Sources</div>');
     for (var i = 0; i < data.xtargets.length && i < SourceMax; i++ ) {
         termlists.push('<a href="#" target_id='+data.xtargets[i].id
             + ' onclick="limitTarget(this.getAttribute(\'target_id\'), this.firstChild.nodeValue);return false;">' + data.xtargets[i].name 
         + ' </a><span> (' + data.xtargets[i].freq + ')</span><br/>');
     }
+    termlists.push('</div>');
      
-    termlists.push('<hr/><div class="termtitle">.::Subjects</div>');
+    termlists.push('<div id="term_subjects" >');
+    termlists.push('<div id="subjects" class="termtitle">.::Subjects</div>');
     for (var i = 0; i < data.subject.length && i < SubjectMax; i++ ) {
         termlists.push('<a href="#" onclick="limitQuery(\'su\', this.firstChild.nodeValue);return false;">' + data.subject[i].name + '</a><span>  (' 
               + data.subject[i].freq + ')</span><br/>');
     }
-     
-    termlists.push('<hr/><div class="termtitle">.::Authors</div>');
+    termlists.push('</div>');
+            
+    termlists.push('<div id="term_authors" >');
+    termlists.push('<div class="termtitle">.::Authors</div>');
     for (var i = 0; i < data.author.length && i < AuthorMax; i++ ) {
         termlists.push('<a href="#" onclick="limitQuery(\'au\', this.firstChild.nodeValue);return false;">' 
                             + data.author[i].name 
@@ -115,8 +160,76 @@ function my_onterm(data) {
                             + data.author[i].freq 
                             + ')</span><br/>');
     }
+    termlists.push('</div>');
     var termlist = document.getElementById("termlist");
     replaceHtml(termlist, termlists.join(''));
+    var d;
+/*
+    for (d in ("xtargets", "subjects", "authors")) {
+       alert(d);
+       if (tab == d)
+               document.getElementById("term_" + d).style.display = '';
+       else 
+               document.getElementById("term_" +d ).style.display = 'none';
+    }
+*/
+    showhide();
+}
+
+function serialize(array) {
+       var t = typeof (obj);
+       if (t != "object" || obj === null) {
+               // simple data type
+               return String(obj);
+       } else {
+               // recurse array or object
+               var n, v, json = [], arr = (obj && obj.constructor == Array);
+               for (n in obj) {
+                       v = obj[n];
+                       t = typeof (v);
+                       if (t == "string")
+                               v = '"' + v + '"';
+                       else if (t == "object" && v !== null)
+                               v = JSON.stringify(v);
+                       json.push((arr ? "" : '"' + n + '":') + String(v));
+               }
+               return (arr ? "" : "") + String(json) + (arr ? "]" : "}");
+       }
+}
+
+var termlist = {};
+function my_onterm_iphone(data) {
+    my_onterm(data);
+    var targets = "";
+    for (var i = 0; i < data.xtargets.length; i++ ) {
+       
+        targets = targets + data.xtargets[i].id + "|" + data.xtargets[i].name + "|" + data.xtargets[i].freq + "\n";
+    }
+    termlist["xtargets"] = targets;
+    var subjects = "";
+    for (var i = 0; i < data.subject.length; i++ ) {
+        subjects = subjects + "-" + "|" + data.subject[i].name + "|" + data.subject[i].freq + "\n";
+    }
+    termlist["subjects"] = subjects;
+    var authors = "";
+    for (var i = 0; i < data.author.length; i++ ) {
+        authors = authors + "-" + "|" + data.author[i].name + "|" + data.author[i].freq + "\n";
+    }
+    termlist["authors"] = authors;
+    //document.getElementById("log").innerHTML = targets + "\n" + subjects + "\n" + authors;
+    callback.send("termlist", "refresh");
+}
+
+function getTargets() {
+       return termlist['xtargets'];
+}
+
+function getSubjects() {
+       return termlist['subjects'];
+}
+
+function getAuthors() {
+       return termlist['authors'];
 }
 
 function my_onrecord(data) {
@@ -131,6 +244,12 @@ function my_onrecord(data) {
     recordDiv.innerHTML += html;
 }
 
+function my_onrecord_iphone(data) {
+    my_onrecord(data);
+    callback.send("record", data.recid, data, data.xtargets[i].freq);
+}
+
+
 function my_onbytarget(data) {
     var targetDiv = document.getElementById("bytarget");
     var table ='<table><thead><tr><td>Target ID</td><td>Hits</td><td>Diags</td>'
@@ -158,6 +277,8 @@ function domReady ()
     document.search.query.value = '';
     document.select.sort.onchange = onSelectDdChange;
     document.select.perpage.onchange = onSelectDdChange;
+    if (!inApp)
+       document.getElementById("heading").style.display="";
 }
 
 // when search button pressed
@@ -201,6 +322,7 @@ function limitQuery (field, value)
 {
     document.search.query.value += ' and ' + field + '="' + value + '"';
     onFormSubmitEventHandler();
+    showhide("recordview");
 }
 
 // limit by target functions
@@ -215,6 +337,7 @@ function limitTarget (id, name)
     resetPage();
     loadSelect();
     triggerSearch();
+    showhide("recordview");
     return false;
 }
 
index 01a13d8..e741145 100644 (file)
@@ -6,13 +6,15 @@
  <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>Pazpar2 demo client</title>
-  <link rel="stylesheet" href="styles.css"></link>
   <script type="text/javascript" src="/pazpar2/js/pz2.js"></script>
+  <script type="text/javascript" src="iphone.js" ></script>
   <script type="text/javascript" src="example_client.js"></script>
+  <link rel="stylesheet" href="/UiUIKIT/stylesheets/iphone.css" />
+  <link rel="apple-touch-icon" href="/UiUIKIT/stylesheets/images/apple-touch-icon.png" />
  </head>
  
- <body onload="domReady();">
-
+ <body id="normal" onload="domReady();">
+    <div id="log" style="display: none;"></div>
   <div id="noscript">
     <noscript>
        <p>Your browser does not support or allow execution of scripts required by this site to work properly.</p>
     </noscript>
   </div>
 
-  <div id="switchmenu" style="visibility:hidden" >
+  <div id="switchmenu" style="display:none" >
    <a href="#" onclick="switchView('recordview')">Record Browser</a>
    <span> | </span>
    <a href="#" onclick="switchView('targetview')">Target Info</a>
   </div>
  
-  <div id="heading" >
+  <div id="heading" style="display:none">
    <table width="100%" border="0" cellpadding="6" cellspacing="0">
     <tr>
 <!--
-     <td width="250" style="visibility:hidden" height="100" align="center"><b>Pazpar2</b></td>
+     <td style="visibility:hidden;" height="100" align="center"><b>Pazpar2</b></td>
 -->
-     <td>
+     <td width="100%">
       <form id="searchForm" name="search">
-       <input id="query" type="text" size="50"/>
-       <input id="button" type="submit" value="Search"/>
+       <input id="query" type="text" />
+<!--  
+       <input id="button" type="submit" value="Search" />
+-->
       </form>
      </td>
+    </tr>
+    <tr>
+     <td  width="100%">
+         <div id="tabs>
+           <a href="javascript:showhide()"></a>
+           <a href="javascript:showhide('recordview')">Results</a>
+           <a href="javascript:showhide('xtargets')">Sources</a>
+           <a href="javascript:showhide('subjects')">Subjects</a>
+           <a href="javascript:showhide('authors')">Authors</a>
+        <a href="javascript:showhide('sort')">Sort</a>
+         </div>   
+        </td>
+     
 <!--
-     <td style="visibility:hidden" >
+     <td style="visibility:hidden;" >
       <a href="http://www.indexdata.com"><img border="0" title="IndexData home page" src="indexdata_logo.png" height="98" align="right" alt="" /></a>
      </td>
 -->
     </tr>
    </table>
   </div>
+    
+  <div id="termlist"></div>
   
   <div id="recordview">
    <table width="100%" border="0" cellpadding="6" cellspacing="0">
-    <tr>
-<!--
-     <td width="250" valign="top" style="visibility:hidden;">
-      <div id="termlist"></div>
-     </td>
--->
+   <tr>
      <td valign="top">
-      <div id="ranking" style="visibility:hidden;">
+      <div id="ranking" style="display: none;">
        <form name="select">
         Sort by
         <select name="sort" id="sort">
         and show 
         <select name="perpage" id="perpage">
          <option value="10">10</option>
-         <option value="20" selected="selected">20</option>
+         <option value="20">20</option>
          <option value="30">30</option>
-         <option value="50">50</option>
+         <option value="50" selected="selected">50</option>
         </select>
         per page.
        </form>
       </div>
-      <div id="pager"></div>
+      <div id="pager" style="display: none;"></div>
       <div id="navi"></div>
-      <div id="results"></div>
+      <h4>Results</h4>
+      <ul id="results">
+      </ul>
      </td>
     </tr>
    </table>
       <div id="stat"></div>
       <span>Copyright &copy; 1999-2010 by <a href="http://www.indexdata.com">Index Data</a></span> 
   </div>
-  <div id="termlist" style="visibility:hidden;"></div>
  </body>
 </html>
diff --git a/www/iphone/iphone.js b/www/iphone/iphone.js
new file mode 100644 (file)
index 0000000..8a71600
--- /dev/null
@@ -0,0 +1,86 @@
+var count = 0;
+var termlist = {};
+var JSON = JSON || {};
+var inApp = false;
+
+var callback = {};
+
+callback.init = function() {
+       if (!inApp) {
+               callback.type = 'browser';
+               document.getElementById("heading").style.display="";
+       } else
+               callback.type = 'iphone';
+
+       var searchdiv = document.getElementById("searchdiv");
+       if (this.type != 'iphone') {
+               searchdiv.style.display = '';
+               document.search.onsubmit = onFormSubmit;
+       }
+       else
+               searchdiv.style.display = 'none';
+};
+
+String.prototype.replaceAll = function(stringToFind,stringToReplace) {
+               var temp = this;
+               var index = temp.indexOf(stringToFind);
+               while(index != -1){
+                       temp = temp.replace(stringToFind,stringToReplace);
+                       index = temp.indexOf(stringToFind);
+               }
+               return temp;
+    }
+
+callback.send = function() 
+{
+       var args = [].splice.call(arguments,0);
+       for (var i = 0; i < args.length; i++) {
+               if (args[i])
+                       args[i] = args[i].replaceAll(':','_'); 
+               else 
+                       alert("args was null: " + i);
+       }
+       var message = "myapp:" + args.join(":");
+       if (this.type == 'iphone')
+               document.location = message;
+       else
+               document.getElementById("log").innerHTML = message;
+}
+
+// implement JSON.stringify serialization
+JSON.stringify = JSON.stringify || function(obj) {
+       var t = typeof (obj);
+       if (t != "object" || obj === null) {
+               // simple data type
+               if (t == "string")
+                       obj = '"' + obj + '"';
+               return String(obj);
+       } else {
+               // recurse array or object
+               var n, v, json = [], arr = (obj && obj.constructor == Array);
+               for (n in obj) {
+                       v = obj[n];
+                       t = typeof (v);
+                       if (t == "string")
+                               v = '"' + v + '"';
+                       else if (t == "object" && v !== null)
+                               v = JSON.stringify(v);
+                       json.push((arr ? "" : '"' + n + '":') + String(v));
+               }
+               return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
+       }
+};
+
+function search(message) {
+       document.search.query.value = message;
+       onFormSubmitEventHandler();
+       return false;
+}
+
+function loaded() {
+       callback.init();
+}
+
+function onFormSubmit() {
+       return search(document.search.query.value);
+}