Greetings,

I just got Jyve up & running this weekend, and thought I would contribute
a patch for something that has been bothering me.  After trying to read
through the entire FAQ for the Java Apache Project, I discovered that
navigation between questions in the FAQ is annoyingly hard.  So I created
a new navigation element that adds previous/next question links to the top
of the question/answer page.  The patch is included below, and it is also
available at http://www.pscs.org/~gmorris/source.html.

I do not have a publicly-accessible server on which to put a working demo,
but I have included a screen shot of the changes at the URL above.

I do not consider this patch quite finished.  There are a couple issues I
would like to polish up.  One, I am not sure the link style I chose fits
with the motif of the page.  I created the links in the style of the
bottom option links (i.e. "[ Link ]") - mostly for simplicity - but I am
wondering if they would be better off in a table, using the same style as
the top navigation.

What are the implications of adding localization strings and configuration
settings?  I assume any strings added to the localization files must be
added to *all* the localization files.  Is it ok to add English strings to
the non-English locales until somebody else can correct them?  Also, if I
wanted to add a configuration option to the TurbineResources.properties
file, should I get permission from somebody to do that first?  (I was
considering making inclusion of the prev/next navbar configurable via the
properties file.  I guess the other question would be, does anybody else
think that is really necessary?)


I am considering taking on these two items from the Jyve TODO, unless
somebody else is already working on them:

    o add the ability to move items around in the system.
    
    o allow someone to be able to add a new question without having to
      select the topic heading first.


                                -- Greg Morris



PS: This patch applies cleanly using "patch -p0" from the top-level Jyve
    source directory, as of 14:30 PDT today.

################## patch starts here
--- src/java/org/apache/jyve/navigations/PrevNextQuestion.java.orig     Sun Jul  2 
11:31:36 2000
+++ src/java/org/apache/jyve/navigations/PrevNextQuestion.java  Sun Jul  2 11:23:17 
+2000
@@ -0,0 +1,345 @@
+package org.apache.jyve.navigations;
+
+/*
+ * Copyright (c) 1997-1999 The Java Apache Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Java Apache
+ *    Project for use in the Apache JServ servlet engine project
+ *    <http://java.apache.org/>."
+ *
+ * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Jyve",
+ *    "Apache Jyve", "Jyve Project", "Apache Jyve Project" and
+ *    "Java Apache Project" must not be used to endorse or promote products
+ *    derived from this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called "Apache JServ"
+ *    nor may "Apache" nor "Apache JServ" appear in their names without
+ *    prior written permission of the Java Apache Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Java Apache
+ *    Project for use in the Apache JServ servlet engine project
+ *    <http://java.apache.org/>."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Java Apache Group. For more information
+ * on the Java Apache Project and the Apache JServ Servlet Engine project,
+ * please see <http://java.apache.org/>.
+ *
+ */
+
+// TODO: Below is all the stuff TopBar.java imports.
+// It would be nice to figure out how much of it we
+// truly need & remove the rest
+
+
+// Java Core Classes
+import java.io.*;
+import java.sql.*;
+import java.util.*;
+
+// Java Servlet Classes
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+// External Stuff
+import org.apache.turbine.modules.*;
+import org.apache.turbine.services.localization.Localization;
+import org.apache.turbine.services.resources.TurbineResources;
+import org.apache.turbine.util.*;
+import org.apache.turbine.om.security.*;
+import org.apache.turbine.util.db.*;
+import org.apache.turbine.util.db.pool.*;
+import org.apache.jyve.util.*;
+import com.workingdogs.village.*;
+import org.apache.ecs.*;
+import org.apache.ecs.html.*;
+
+/**
+ * A navigation element providing previous/next navigation within
+ * question screens.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Greg Morris</a>
+ */
+
+public class PrevNextQuestion extends Navigation
+{
+    public ConcreteElement doBuild( RunData data ) throws Exception
+    {
+        int visitorid = data.getUser().getId();
+        Integer project_id = (Integer) data.getUser().getTemp("project_id", 
+                                data.getParameters().getInteger("project_id", -1));
+        Integer faq_id = (Integer) data.getUser().getTemp("faq_id",
+                                data.getParameters().getInteger("faq_id", -1));
+        Integer topic_id = (Integer) data.getUser().getTemp("topic_id", 
+                                data.getParameters().getInteger("topic_id", -1));
+        Integer question_id = (Integer) data.getUser().getTemp("question_id", 
+                                data.getParameters().getInteger("question_id", -1));
+
+        JSecurityCheck secCheck = new JSecurityCheck(data);
+        boolean showUnreleasedQuestion =
+            ( secCheck.permissionToRelease("question") )
+            || ( secCheck.permissionToSeeUnreleased("question") );
+        boolean showUnreleasedTopic =
+            ( secCheck.permissionToRelease("topic") )
+            || ( secCheck.permissionToSeeUnreleased("topic") );
+
+        StringBuffer sql = new StringBuffer();
+        sql.append ( "select" );
+        sql.append ( " question.question_id, question.question_value, 
+question.released" );
+        sql.append ( " from question" );
+        sql.append ( " where" );
+        sql.append ( " question.topic_id=" );
+        sql.append ( topic_id );
+        sql.append ( " and question.deleted='N'" );
+
+        if (!showUnreleasedQuestion)
+        {
+            // select if the question is released or it was created by the current 
+visitor
+            sql.append ( " AND (question.released='Y' OR question.visitorid=");
+            sql.append ( visitorid );
+            sql.append ( ")");
+        }
+
+        sql.append ( " order by" );
+        sql.append ( " question.display_order" );
+        // Order alphabetical, if same order number
+        sql.append ( ",question.question_value" );
+
+        // get a connection to the db
+        DBConnection db = DBBroker.getInstance().getConnection();
+        Connection connection = db.getConnection();
+
+        // execute the query
+        QueryDataSet qds = new QueryDataSet( connection, sql.toString() );
+
+        try
+        {
+            qds.fetchRecords();
+            int size = qds.size();
+            if ( size == 0 )
+            {
+                // huh?  no questions for the topic this question is
+                // supposedly in?
+                return null;
+            }
+
+            int qid = question_id.intValue();
+            int thisIndex = -1;
+            for ( int i = 0; i < size; ++i )
+            {
+                if ( qid == qds.getRecord(i).getValue("question_id").asInt() )
+                {
+                    thisIndex = i;
+                    break;
+                }
+            }
+
+            if ( thisIndex == -1 )
+            {
+                // our question was not found in the
+                // list of questions for this topic
+                return null;
+            }
+
+            Record prevQuestion;
+            Record nextQuestion;
+            if ( (thisIndex-1) >= 0 )
+                prevQuestion = qds.getRecord(thisIndex - 1);
+            else
+                prevQuestion = null;    // the current question is the first question
+
+            if ( (thisIndex+1) < size )
+                nextQuestion = qds.getRecord(thisIndex + 1);
+            else
+                nextQuestion = null;    // the current question is the last question
+
+            A prevLink = null;
+            A nextLink = null;
+
+            if ( prevQuestion != null )
+            {
+                prevLink = new A().setHref(
+                    new DynamicURI(data, "DisplayQuestionAnswer", "SetAll")
+                        .addPathInfo("project_id", project_id)
+                        .addPathInfo("faq_id", faq_id)
+                        .addPathInfo("topic_id", topic_id)
+                        .addPathInfo("question_id",
+                                     prevQuestion.getValue("question_id").asInt())
+                        .toString()
+                        
+).addElement(prevQuestion.getValue("question_value").asString());
+            }
+            if ( nextQuestion != null )
+            {
+                nextLink = new A().setHref(
+                    new DynamicURI(data, "DisplayQuestionAnswer", "SetAll")
+                        .addPathInfo("project_id", project_id)
+                        .addPathInfo("faq_id", faq_id)
+                        .addPathInfo("topic_id", topic_id)
+                        .addPathInfo("question_id",
+                                     nextQuestion.getValue("question_id").asInt())
+                        .toString()
+                        
+).addElement(nextQuestion.getValue("question_value").asString());
+            }
+
+
+            sql = new StringBuffer();
+            sql.append ( "select" );
+            sql.append ( " topic.topic_id, topic.topic_value, topic.released" );
+            sql.append ( " from topic, faq" );
+            sql.append ( " where" );
+            sql.append ( " faq.faq_id=topic.faq_id" );
+            sql.append ( " and topic.faq_id=" );
+            sql.append ( faq_id );
+            sql.append ( " and topic.deleted='N'" );
+
+            if ( !showUnreleasedTopic )
+            {
+                sql.append ( " AND (topic.released='Y' OR topic.visitorid=" );
+                sql.append ( visitorid );
+                sql.append ( ")" );
+            }
+
+            sql.append ( " and faq.deleted='N'" );
+            sql.append ( " order by" );
+            sql.append ( " topic.display_order,topic.topic_value" );
+
+            qds = new QueryDataSet ( connection, sql.toString() );
+            qds.fetchRecords();
+
+            size = qds.size();
+            if ( size == 0 )
+            {
+                // huh?  no topics for the faq this topic is
+                // supposedly in?
+                return null;
+            }
+
+            int tid = topic_id.intValue();
+            thisIndex = -1;
+            for ( int i = 0; i < size; ++i )
+            {
+                if ( tid == qds.getRecord(i).getValue("topic_id").asInt() )
+                {
+                    thisIndex = i;
+                    break;
+                }
+            }
+
+            if ( thisIndex == -1 )
+            {
+                // our topic was not found in the
+                // list of topics for this faq
+                return null;
+            }
+
+            Record thisTopic = qds.getRecord(thisIndex);
+            Record prevTopic;
+            Record nextTopic;
+
+            if ( (thisIndex-1) < 0 )
+                prevTopic = null;       // the current topic is the first topic
+            else
+                prevTopic = qds.getRecord(thisIndex - 1);
+
+            if ( (thisIndex+1) >= size )
+                nextTopic = null;       // the current topic is the last topic
+            else
+                nextTopic = qds.getRecord(thisIndex + 1);
+
+            A topicLink = new A().setHref(
+                new DynamicURI(data, "DisplayOneTopic", "SetAll")
+                    .addPathInfo("project_id", project_id)
+                    .addPathInfo("faq_id", faq_id)
+                    .addPathInfo("topic_id", topic_id)
+                    .toString()
+                    ).addElement(thisTopic.getValue("topic_value").asString());
+
+            if ( prevLink == null && prevTopic != null )
+            {
+                prevLink = new A().setHref(
+                    new DynamicURI(data, "DisplayOneTopic", "SetAll")
+                        .addPathInfo("project_id", project_id)
+                        .addPathInfo("faq_id", faq_id)
+                        .addPathInfo("topic_id",
+                                     prevTopic.getValue("topic_id").asInt())
+                        .toString()
+                        ).addElement(prevTopic.getValue("topic_value").asString());
+            }
+            if ( nextLink == null && nextTopic != null )
+            {
+                nextLink = new A().setHref(
+                    new DynamicURI(data, "DisplayOneTopic", "SetAll")
+                        .addPathInfo("project_id", project_id)
+                        .addPathInfo("faq_id", faq_id)
+                        .addPathInfo("topic_id",
+                                     nextTopic.getValue("topic_id").asInt())
+                        .toString()
+                        ).addElement(nextTopic.getValue("topic_value").asString());
+            }
+
+            P navText = new P();
+            // TODO: Add localization
+            if ( prevLink != null )
+            {
+                navText.addElement ( "[ Previous: " );
+                navText.addElement ( prevLink );
+                navText.addElement ( " ]" );
+            }
+            else
+            {
+                navText.addElement ( "[ First question in first topic ]" );
+            }
+
+            navText.addElement ( " [ Current Topic: " );
+            navText.addElement ( topicLink );
+            navText.addElement ( " ] " );
+
+            if ( nextLink != null )
+            {
+                navText.addElement ( "[ Next: " );
+                navText.addElement ( nextLink );
+                navText.addElement ( " ]" );
+            }
+            else
+            {
+                navText.addElement ( "[ Last question in last topic ]" );
+            }
+
+            return navText;
+        }
+        finally
+        {
+            qds.close();
+            DBBroker.getInstance().releaseConnection(db);
+        }
+    }
+}
--- src/java/org/apache/jyve/screens/DisplayQuestionAnswer.java.orig    Sun Jul  2 
11:30:53 2000
+++ src/java/org/apache/jyve/screens/DisplayQuestionAnswer.java Sun Jul  2 11:04:33 
+2000
@@ -130,6 +130,15 @@
             NavigationLoader.getInstance().eval ( data, "TopBar" ) );
         ec.addElement ( new P() );
 
+        // Added Sat Jul  1 16:57:28 PDT 2000
+        // by Greg Morris <[EMAIL PROTECTED]>
+        // in an attempt to put a previous/next
+        // navigation on the question page
+
+        Element prevNext = NavigationLoader.getInstance().eval ( data, 
+"PrevNextQuestion" );
+        if ( prevNext != null )
+            ec.addElement ( prevNext );
+
         // get a connection to the db
         DBConnection db = DBBroker.getInstance().getConnection();
         Connection connection = db.getConnection();



--
--------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Archives and Other:  <http://java.apache.org/main/mail.html>
Problems?:           [EMAIL PROTECTED]

Reply via email to