Joomla! (DAY 6) - Joomsport (DAY 4): Tackling with View's Parameters - JElement

62 篇文章 0 订阅

JElement: The interface for Parameter of a View


There is one more piece of the puzzle! That is about "ltable" view. Its template's metadata file:


<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="Season Table Layout">
		<message>
			<![CDATA[Season Table Layout]]>
		</message>
	</layout>
	<state>
		<name>Season Table Layout</name>
		<description>Season Table Layout</description>
		<url addpath="/administrator/components/com_joomsport/elements">
			<param name="sid" type="season" default="0" label="Select Season" description="Season" />
			<param name="gr_id" type="season" default="0" label="Select Group" description="Group" />
		</url>
		<params>
		</params>
	</state>
</metadata>

There are two 'param' nodes inside 'url' node, and they have the same value for 'type' attribute: "season". As explored in previous days, this description will lead Joomla! to load the 'season.php' under '/administrator/components/com_joomsport/elements/', and the question is why to load single 'season' element for both the two parameters? Now take a look at what does 'season.php' do on the neath: 

<?php
defined('_JEXEC') or die( 'Restricted access' );
class JElementSeason extends JElement
{
	/**
	 * Element name
	 *
	 * @access	protected
	 * @var		string
	 */
	var	$_name = 'Season';
	function fetchElement($name, $value, &$node, $control_name)
	{
		//echo 'reach here, in fetchElement()';
		global $mainframe;

		$db			=& JFactory::getDBO();
		$doc 		=& JFactory::getDocument();
		$template 	= $mainframe->getTemplate();
		$fieldName	= $control_name.'['.$name.']';
		$article->title = '';

		//dump($name, 'name');
		//dump($value, 'value');
		//dump($node, 'node');
		//dump($control_name, 'control_name');

		if($name == 'sid')
		{
			if ($value)
			{
				//echo 'reach here, in fetchElement, value is valid';
				$query = "SELECT CONCAT(t.name,' ',s.s_name) as name FROM #__bl_tournament as t, #__bl_seasons as s WHERE s.t_id = t.id AND s.s_id = ".$value;
				$db->setQuery($query);

				$rows = $db->loadObjectList();
				if(isset($rows[0]))
				{
					$row = $rows[0];
					$article->title = $row->name;
				}
			}
			else
			{
				echo 'reach here, in fetchElement, value is invalid';
				$article->title = JText::_('Select Season');
			}
			$task = 'season_menu';
		}
		else
		{
			if ($value)
			{
				$query = "SELECT group_name FROM #__bl_groups  WHERE id = ".$value;
				$db->setQuery($query);

				$rows = $db->loadObjectList();
				if(isset($rows[0]))
				{
					$row = $rows[0];
					$article->title = $row->group_name;
				}
			}
			else
			{
				$article->title = JText::_('Select Group');
			}
			$task = 'group_menu';
		}
		$js = "
		function jSelectArticle(id, title, object) " .
		"{
			document.getElementById(object + '_id').value = id;
			document.getElementById(object + '_name').value = title;
			document.getElementById('sbox-window').close();
		}";
		$doc->addScriptDeclaration($js);
		$link = 'index.php?option=com_joomsport&task='.$task.'&tmpl=component&object='.$name;
		JHTML::_('behavior.modal', 'a.modal');
		$html = "\n".'<div style="float: left;"><input style="background: #ffffff;" type="text" id="'.$name.'_name" value="'.htmlspecialchars($article->title, ENT_QUOTES, 'UTF-8').'" disabled="disabled" /></div>';
		$html .= '<div class="button2-left"><div class="blank"><a class="modal" title="'.$article->title.'"  href="'.$link.'" rel="{handler: \'iframe\', size: {x: 650, y: 375}}">'.JText::_('Select').'</a></div></div>'."\n";
		$html .= "\n".'<input type="hidden" id="'.$name.'_id" name="'.$fieldName.'" value="'.(int)$value.'" />';
		return $html;
	}
}

In fact it define one class 'JElementSeason' which extends 'JElement' in Joomla! framework, and this class have one method 'fetchElement'


According to the body of 'fetchElement', its main job is to generate the HTML code for the 'Element' of a menu type, namely the UI for parameters of a view. The two 'param' nodes inmetadata.xml cause Joomla! to call 'fetchElement' twice, and generate the two parameters' setting interface(please note: the generated HTML doesn't include the popup data list for selecting):


param-set-element


Then method 'fetchElement' should be able to discriminate the two conditions, and in fact it does be, it does that by checking '$name' value. And what are the values passed to this method? Put 'dump' inside it to see:


		dump($name, 'name');
		dump($value, 'value');
		dump($node, 'node');
		dump($control_name, 'control_name');

dump


The var '$node' is never referenced, and '$control_name' is a fixed string for these cases, so we can igorne them. Then the relation between the method 'fetchElement' and the 'metadata.xml' is: 


params


Inside 'fetchElement', '$value' is used as season id for database query():


if ($value)
{
	$query = "SELECT CONCAT(t.name,' ',s.s_name) as name FROM #__bl_tournament as t, #__bl_seasons as s WHERE s.t_id = t.id AND s.s_id = ".$value;
	$db->setQuery($query);

	......
}
else
{
	$article->title = JText::_('Select Season');
}

Please note: these queries are only for determining the text to display in the text field("主席碟 2011-2012", for example). But because passed value for argument '$value' is always '0', the control flow will never reach the if block, it will always reach else block instead, so you will see "Select Season" instruction instead, for your first time specifying that type for a menu. This is a trick, since in MySQL, 1 will be used as seed for auto-augument field, so '0' is used for indicating no record specified.


The two links for getting the data list generated by this method is:


for sid:

http://localhost/soccer/administrator/index.php?option=com_joomsport&task=season_menu&tmpl=component&object=sid

for gr_id:

http://localhost/soccer/administrator/index.php?option=com_joomsport&task=group_menu&tmpl=component&object=gr_id

The relevent code is:


$link = 'index.php?option=com_joomsport&task='.$task.'&tmpl=component&object='.$name;




Back End Controller: predefining the tasks for popup the data list


Basing on Joomla! 's mechanism, the joomsport component for admin should have handlers for task 'season_menu' and 'group_menu': 


admin.joomsport.php:

function BL_Season_Menu($option)
{
	$db =& JFactory::getDBO();
	$query = "SELECT s.s_id as id, CONCAT(t.name,' ',s.s_name) as name FROM #__bl_tournament as t, #__bl_seasons as s WHERE s.published = '1' AND t.published = '1' AND s.t_id = t.id AND s.t_id = t.id ORDER BY t.name, s.s_name";
	$db->setQuery($query);
	$row = $db->loadObjectList();
	joomsport_html::bl_SeasonMenu($row, $option);
}

function BL_Group_Menu($option)
{
	$mainframe = JFactory::getApplication();

	$limit	= $mainframe->getUserStateFromRequest( 'global.list.limit', 'limit', $mainframe->getCfg('list_limit'), 'int' );
	$limitstart = $mainframe->getUserStateFromRequest( $option.'.limitstart', 'limitstart', 0, 'int' );

	$db =& JFactory::getDBO();
	$query = "SELECT COUNT(*) FROM #__bl_groups as g, #__bl_tournament as t, #__bl_seasons as s WHERE s.t_id = t.id AND s.s_id=g.s_id";
	$db->setQuery($query);
	$total = $db->loadResult();

	jimport('joomla.html.pagination');
	$pageNav = new JPagination( $total, $limitstart, $limit );

	$query = "SELECT g.*,CONCAT(t.name,' ',s.s_name) as name FROM #__bl_groups as g, #__bl_tournament as t, #__bl_seasons as s WHERE s.t_id = t.id AND s.s_id=g.s_id ORDER BY g.group_name";
	$db->setQuery($query, $pageNav->limitstart, $pageNav->limit);
	$rows = $db->loadObjectList();
	joomsport_html::bl_GroupMenu($rows, $option);
}

switch (JRequest::getCmd('task'))
{
	......
	
	//---menu-------------//
	case 'season_menu':			BL_Season_Menu($option);				break;
	......
	case 'group_menu':			BL_Group_Menu($option);					break;
	
	......

}


So, to sum up, JElement class its responsiblity is to generate the HTML user control for parameters of view, to let user to select value for that parameter, it also generate a link to the component to generate the popup data list, and component's controller should take care of generating the list. Each parameter panel has a hidden input field, which holds the value for that parameter:


parameter-hidden-input


The line to generate the input field is:

$html .= "\n".'<input type="hidden" id="'.$name.'_id" name="'.$fieldName.'" value="'.(int)$value.'" />';

And the js code for updating its value:


$js = "
function jSelectArticle(id, title, object) " .
"{
	document.getElementById(object + '_id').value = id;
	document.getElementById(object + '_name').value = title;
	document.getElementById('sbox-window').close();
}";






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值