javaeye博客的收藏管理页面,收藏分类是通过下拉列表选择来录入已有分类标签的,这个功能非常方便实用,因为不用死记旧标签,还提高了标签的录入效率,于是决定自己模仿也搞一个。
在开始之前,先说明一下,以下的模仿过程全部处于FleaPHP框架之下,数据库为MySQL。
以下为功能实现的整个过程。
第一步:相关数据表准备
先创建一个文章管理数据表articles,该表含有一个自增量字段art_id。
接着创建一个分类标签数据表tags,其表结构如下图所示:
再创建一个中间表articles_tags,其表结构如下图所示:
第二步:编写数据表对象代码
1、编写文章数据表对象代码。如下所示:
<?php FLEA::loadClass('FLEA_Db_TableDataGateway'); /** * 文章数据表对象 */ class Table_Articles extends FLEA_Db_TableDataGateway { var $tableName = 'articles'; var $primaryKey = 'art_id'; /** * 定义多对多关系 * */ var $manyToMany = array( array( 'tableClass' => 'Table_Tags', 'joinTable' => 'articles_tags', 'foreignKey' => 'art_id', 'assocforeignKey' => 'tag_id', 'mappingName' => 'tags', 'enabled' => false ) ); } ?>
2、编写分类标签数据表对象代码。如下所示:
<?php FLEA::loadClass('FLEA_Db_TableDataGateway'); /** * 分类标签数据表对象 */ class Table_Tags extends FLEA_Db_TableDataGateway { var $tableName = 'tags'; var $primaryKey = 'tag_id'; } ?>
第三步:编写模型对象类代码
1、编写分类标签模型对象类代码。如下所示:
<?php /** * 分类标签模型对象类 */ class Model_Tags { var $_tblTags; /** * 构造函数 * */ function Model_Tags() { $this->_tblTags = & FLEA::getSingleton('Table_Tags'); } /** * 生成标签下拉列表HTML代码 */ function makeTagsDropdownlist() { $ui = & FLEA::initWebControls(); FLEA::loadFile('FLEA_Helper_Array.php'); $rows = $this->_tblTags->findAll(); // 增加一个下拉选择项在最前面 array_unshift($rows, array('tag_id' => 0, 'label' => '选择已有分类')); $items = array_to_hashmap($rows, 'label', 'tag_id'); return $ui->control( 'dropdownlist', 'tagsel', // 下拉列表ID array( 'items' => $items, //'selected' => null, ), true // 指示返回html代码,如果为false,则不返回 ); } } ?>
2、编写文章模型对象代码。如下所示:
<?php /** * 文章模型对象 */ class Model_Articles { var $_tblArt; /** * 构造函数 * */ function Model_Articles() { $this->_tblArt = & FLEA::getSingleton('Table_Articles'); } /** * 完成对文章条目所关联的 tags 的处理 * * @param array $row */ function _processTags(& $row) { // 读出数据库现有的所有 tags $tblTags = & FLEA::getSingleton('Table_Tags'); $rows = $tblTags->findAll(null); FLEA::loadFile('FLEA_Helper_Array.php'); $existsTags = array_to_hashmap($rows, 'label', 'tag_id'); // 处理用户输入的 tags $labels = explode(',', $row['tags']); //$labels = explode(',', $tags); $tagsIdList = array(); foreach ($labels as $label) { $label = strtolower(trim($label)); if ($label == '') { continue; } if (isset($existsTags[$label])) { // 将文档登记到现有 tag $tagsIdList[] = $existsTags[$label]; } else { // 创建新 tag,并登记文档 $tag = array('label' => $label); $tagsIdList[] = $tblTags->create($tag); } } $row['tags'] = $tagsIdList; //return $tagsIdList; } /** * 新增文章 * * @param array $row * @return int */ function create(& $row) { $this->_processTags($row); $this->_tblArt->enableLink('tags'); return $this->_tblArt->create($row); } /** * 更新文章 * * @param array $row * @return int */ function update(& $row) { $this->_processTags($row); $this->_tblArt->enableLink('tags'); return $this->_tblArt->update($row); } } ?>
第四步、编写HTML模板代码
因为要利用到jQuery,所以模板文件要引入jQuery库文件。如下所示:
<!-- // 引入 jQuery 库文件 --> <script type="text/javascript" src="jquery-1.4.2.min.js"></script>
模板文件中与标签相关的HTML代码:
<tr> <td>分类标签:</td> <td><input name="tags" type="text" id="tags" size="30" /> {{ $art.taglist }}*多个标签之间用半角逗号分隔</td> </tr>
编写选择录入已有标签的JavaScript代码:
<script type="text/javascript"> $(function() { $("#tagsel").change(function(){ var txt = $("option:selected", this).text(); if (txt == '选择已有分类') { txt = ''; } else { var label = $("#tags").val(); if (label) { txt = label + ', ' + txt; } } $("#tags").val(txt); }); }); </script>
第五步:编写后台文章控制器类代码
<?php /** * 办公网站后台管理——文章管理控制器类 * * 文 件 名:Admin/Controller/Article.php * 作 者:hegz * 更新时间:2010/05/07 * */ /** * 装入后台管理控制器基类 */ //{{ FLEA::loadClass('Controller_AdminBase'); //}} class Controller_Article extends Controller_AdminBase { var $_modelArt; /** * 构造函数 * */ function Controller_Article() { parent::Controller_AdminBase(); $this->_modelArt = & FLEA::getSingleton('Model_Articles'); } /** * 显示新增文档界面操作 * */ function actionAdd() { ...... $tags = & FLEA::getSingleton('Model_Tags'); $data = array( 'header' => '攒写文档', 'action' => $this->_url('Save'), 'taglist' => $tags->makeTagsDropdownlist() // 注意此句代码,生成下拉列表HTML代码 ); ...... $this->tpl->assign('art', $data); // Smarty模板引擎变量替换 ...... } /** * 保存文档操作 * */ function actionSave() { $data = $_POST; ...... if ($data['art_id']) { $this->_modelArt->update($data); $art_id = $data['art_id']; } else { $art_id = $this->_modelArt->create($data); } ...... } }
结束语
上面的实现过程由于要考虑新标签的保存及旧标签的处理,以及文章表与标签表的多对多关联,所以看上去有些复杂。如果不考虑这些实现,就只是下面几行处理标签录入的JavaScript代码的事。
<script type="text/javascript"> $(function() { $("#tagsel").change(function(){ var txt = $("option:selected", this).text(); if (txt == '选择已有分类') { txt = ''; } else { var label = $("#tags").val(); if (label) { txt = label + ', ' + txt; } } $("#tags").val(txt); }); }); </script>
论坛贴:http://qeephp.com/bbs/viewthread.php?tid=10969&page=1&extra=#pid56693