Adds partial tree for jobterms if autocompletion is not enough. Only in profile editing.
authorPascal Corpet <pascal.corpet@m4x.org>
Fri, 22 Oct 2010 20:35:35 +0000 (22:35 +0200)
committerPascal Corpet <pascal.corpet@m4x.org>
Mon, 25 Oct 2010 21:49:24 +0000 (23:49 +0200)
classes/jobterms.php
htdocs/javascript/jobtermstree.js
htdocs/javascript/profile.js

index c791865..418bfc9 100644 (file)
@@ -25,7 +25,15 @@ class JobTerms {
     const ONLY_JOBS = 'jobs';
     const ONLY_MENTORS = 'mentors';
 
-    static public function getSubTerms($parent_jtid, $filter = self::ALL) {
+    /** Retreives subterms of a term to display in a tree
+     * @param $parent_jtid the id of the parent jobterm
+     * @param $filter enable filtering on jobterms that have been used in jobs or in mentors, in
+     *  that case, each row as an 'nb' field that counts all profiles that match
+     * @param $token_filter a text (usually ending by %) the retreived subterms to jobterms that
+     *  contains this tokens or that one of their children contains it.
+     * @return an iterator over jobterms with jtid, name, full_name and nb
+     */
+    static public function getSubTerms($parent_jtid, $filter = self::ALL, $token_filter = null) {
         switch ($filter) {
           case self::ALL:
           default:
@@ -45,6 +53,10 @@ class JobTerms {
         } else {
             $count = $join = '';
         }
+        if (!empty($token_filter)) {
+            $join .= ' INNER JOIN  profile_job_term_relation AS rtf ON (rtf.jtid_1 = e.jtid) '.
+                self::token_join_query(self::tokenize($token_filter), 'rtf', 'jtid_2');
+        }
         return XDB::iterator('SELECT  e.jtid, e.name, e.full_name'.$count.', IF(rf.jtid_1 IS NULL, 1, 0) AS leaf
                                 FROM  profile_job_term_enum AS e
                           INNER JOIN  profile_job_term_relation AS r ON (r.jtid_2 = e.jtid)'.$join.'
@@ -65,11 +77,14 @@ class JobTerms {
      * is chosen
      * @param Env::v('treeid') tree id that will be given as first argument of attrfunc function
      * the second argument will be the chosen job term id and the third one the chosen job's full name.
+     * @param Env::v('text_filter') a string (usually ending by %) that will be used to filter
+     * subbranches, keeping only the one containing this text in its title or in the title of one of
+     * its subbranches.
      */
     static public function ajaxGetBranch(&$page, $filter = self::ALL) {
         pl_content_headers('application/json');
         $page->changeTpl('include/jobterms.branch.tpl', NO_SKIN);
-        $subTerms = self::getSubTerms(Env::v('jtid'), $filter);
+        $subTerms = self::getSubTerms(Env::v('jtid'), $filter, Env::v('text_filter'));
         $page->assign('subTerms', $subTerms);
         switch ($filter) {
           case self::ONLY_JOBS:
@@ -80,6 +95,7 @@ class JobTerms {
             break;
         }
         $page->assign('jtid', Env::v('jtid'));
+        $page->assign('text_filter', Env::v('text_filter'));
         $page->assign('attrfunc', Env::v('attrfunc'));
         $page->assign('treeid', Env::v('treeid'));
     }
@@ -96,7 +112,11 @@ class JobTerms {
                     if (nod != -1) {
                         jtid = nod.attr("id").replace(/^.*_([0-9]+)$/, "$1");
                     }
-                    return { "jtid" : jtid, "treeid" : "'.addslashes($treeid).'", "attrfunc" : "'.addslashes($attrfunc).'" }
+                    return {
+                        "jtid" : jtid,
+                        "treeid" : "'.addslashes($treeid).'",
+                        "attrfunc" : "'.addslashes($attrfunc).'"
+                     }
                 }
             }} });';
     }
@@ -104,7 +124,7 @@ class JobTerms {
     /**
      * Extract search token from term
      * @param $term a utf-8 string that can contain any char
-     * @param an array of elementary tokens
+     * @return an array of elementary tokens
      */
     static public function tokenize($term)
     {
@@ -129,14 +149,15 @@ class JobTerms {
      * Create the INNER JOIN query to restrict search to some job terms
      * @param $tokens an array of the job terms to look for (LIKE comp)
      * @param $table_alias the alias or name of the table with a jtid field to restrict
+     * @param $table_field the name of the field to restrict in table_alias, usually jtid
      * @return a partial SQL query
      */
-    static public function token_join_query(array $tokens, $table_alias) {
+    static public function token_join_query(array $tokens, $table_alias, $table_field = 'jtid') {
         $joins = '';
         $i = 0;
         foreach ($tokens as $t) {
             ++$i;
-             $joins .= ' INNER JOIN  profile_job_term_search AS s'.$i.' ON(s'.$i.'.jtid = '.$table_alias.'.jtid AND s'.$i.'.search LIKE '.XDB::escape($t).')';
+             $joins .= ' INNER JOIN  profile_job_term_search AS s'.$i.' ON(s'.$i.'.jtid = '.$table_alias.'.'.$table_field.' AND s'.$i.'.search LIKE '.XDB::escape($t).')';
         }
         return $joins;
     }
index f3a42eb..d9b438d 100644 (file)
  * @param clickFunc name of a javascript function that will be called when a
  * term is clicked. The three params of this function will be : treeid, the
  * id of the job term clicked, and the full name of the job term clicked.
+ * @param text_filter a string that is tokenized to filter jobtermss shown
+ * in the tree: only terms that contain all the tokens are shown with their
+ * parents.
  */
-function createJobTermsTree(domElement, platalpage, treeid, clickFunc)
+function createJobTermsTree(domElement, platalpage, treeid, clickFunc, text_filter)
 {
     $(domElement).jstree({
         "core" : {"strings":{"loading":"Chargement ..."}},
@@ -42,7 +45,7 @@ function createJobTermsTree(domElement, platalpage, treeid, clickFunc)
                 if (nod != -1) {
                     jtid = nod.attr("id").replace(/^.*_([0-9]+)$/, "$1");
                 }
-                return { "jtid" : jtid, "treeid" : treeid, "attrfunc" : clickFunc }
+                return { "jtid" : jtid, "treeid" : treeid, "attrfunc" : clickFunc, "text_filter": text_filter }
             }
         }} });
 }
index ce2273e..ef2c7ef 100644 (file)
@@ -583,7 +583,7 @@ function removeJobTerm()
 function displayJobTerm(row)
 {
     if (row[1] < 0) {
-        return '... <em>précise ta recherche</em> ...';
+        return '... <em>parcourir les résultats dans un arbre</em> ...';
     }
     return row[0];
 }
@@ -596,26 +596,30 @@ function displayJobTerm(row)
  */
 function selectJobTerm(li)
 {
-    if (li.extra[0] < 0) {
-        return;
-    }
     var jobid = this.extraParams.jobid;
-    addJobTerm(jobid,li.extra[0],$(li).text());
+    if (li.extra[0] >= 0) {
+        addJobTerm(jobid,li.extra[0],$(li).text());
+    }
     var search_input;
     if (jobid < 0) {
         search_input = $('.term_search')[0];
     } else {
         search_input = $('#job_'+jobid+' .term_search')[0];
     }
-    search_input.value = '';
-    search_input.focus();
+    if (li.extra[0] >= 0) {
+        search_input.value = '';
+        search_input.focus();
+    } else {
+        search_input.value = li.selectValue.replace(/%$/,'');
+        toggleJobTermsTree(jobid, li.selectValue);
+    }
 }
 
 /**
  * Function to show or hide a terms tree in job edition
  * @param jobid is the id of the job currently edited
  */
-function toggleJobTermsTree(jobid)
+function toggleJobTermsTree(jobid, textfilter)
 {
     var treepath;
     if (jobid < 0) {
@@ -626,9 +630,11 @@ function toggleJobTermsTree(jobid)
     treepath += '.term_tree';
     if ($(treepath + ' ul').length > 0) {
         $(treepath).empty().removeClass().addClass('term_tree');
-        return;
+        if (!textfilter) {
+            return;
+        }
     }
-    createJobTermsTree(treepath, 'profile/ajax/tree/jobterms/all', 'job' + jobid, 'chooseJobTerm');
+    createJobTermsTree(treepath, 'profile/ajax/tree/jobterms/all', 'job' + jobid, 'chooseJobTerm', textfilter);
 }
 
 /**