154 lines
6.7 KiB
Plaintext
154 lines
6.7 KiB
Plaintext
<cfimport prefix="c" taglib="."/>
|
||
<cfif thisTag.executionMode IS "end">
|
||
<!--- <cfloop collection=#CALLER# item="item">
|
||
<cfset structInsert(variables, item, CALLER[item], false)/>
|
||
</cfloop> --->
|
||
|
||
<cfparam name="ATTRIBUTES.query" type="query"/>
|
||
<cfparam name="ATTRIBUTES.recordsPerPage" type="integer" default="500"/>
|
||
<cfparam name="ATTRIBUTES.nStart" type="integer" default="1"/>
|
||
<cfparam name="ATTRIBUTES.titleMap" type="struct" default=srtuctNew()/><!---for definition see: field_set.cfm--->
|
||
<cfparam name="ATTRIBUTES.sortArray" type="array" default=arrayNew(1)/>
|
||
|
||
<cfset tableAttributeList="query,recordsPerPage,nStart,titleMap,sortArray"/>
|
||
<cfset colAttributeList="lang,th,td,content,field,formatter,sortable,visible,columnOrder"/>
|
||
<cfset tdAttributeList="content,field"/>
|
||
|
||
|
||
<cfparam name="thisTag.columns" type="array"/>
|
||
|
||
|
||
<cffunction name=reorderColumns output="No">
|
||
<!--- Вариант сортировки. Вынимаем все элементы с указанным порядком в отдельную коллекцию,
|
||
после чего вставляем их в оставшуюся коллекцию на указанные позиции.
|
||
нет смысла делать вид, что мы реализуем что-то универсальное
|
||
(поле для сортировки в совершенно конкретном поле структуры в массиве),
|
||
поэтому ничего не передаем в аргументах, спокойно ссылаемся на окружение--->
|
||
<cfset var tmpOrderedIndexes=ArrayNew(1)/>
|
||
<cfset var tmpUnorderedIndexes=ArrayNew(1)/>
|
||
|
||
<cfloop from=1 to=#arrayLen(thisTag.columns)# index="i">
|
||
<cfif thisTag.columns[i].columnOrder GT 0>
|
||
<cfset arrayAppend(tmpOrderedIndexes,i)/>
|
||
<cfelse>
|
||
<cfset arrayAppend(tmpUnorderedIndexes,i)/>
|
||
</cfif>
|
||
</cfloop>
|
||
|
||
<cfloop from=#arrayLen(tmpOrderedIndexes)# to=1 step=-1 index="i">
|
||
<!--- counting up-down preserves entry order for equal columnOrders --->
|
||
<cfset var pos=max(min(thisTag.columns[tmpOrderedIndexes[i]].columnOrder, len(tmpUnorderedIndexes)+1),1)/>
|
||
<cfset arrayInsertAt(tmpUnorderedIndexes,pos,tmpOrderedIndexes[i])/>
|
||
</cfloop>
|
||
|
||
<cfset var sortedColumns=ArrayNew(1)/>
|
||
<cfloop from=1 to=#arrayLen(tmpUnorderedIndexes)# index="i">
|
||
<cfset sortedColumns[i]=thisTag.columns[tmpUnorderedIndexes[i]]/>
|
||
</cfloop>
|
||
|
||
<cfreturn sortedColumns/>
|
||
</cffunction>
|
||
|
||
<cfset sortedColumns=reorderColumns()/>
|
||
|
||
<cfset thisTag.generatedContent=""/>
|
||
|
||
<table<!--- passthrough additional attributes
|
||
---><cfoutput><cfloop collection=#ATTRIBUTES# item="attr"><!---
|
||
---><cfif NOT listFindNoCase(tableAttributeList,attr)<!--- AND isSimpleValue(structFind(ATTRIBUTES,attr))--->> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
|
||
---></cfloop></cfoutput>>
|
||
<thead>
|
||
<tr>
|
||
<cfloop array=#sortedColumns# index="column">
|
||
<cfset th=column.th[1]/>
|
||
<th<!--- атрибуты колонки передаются в TH, хотя это выглядит не очень нужным --->
|
||
<cfloop collection=#column# item="colAttr">
|
||
<cfif NOT listFindNoCase(colAttributeList,colAttr)><cfoutput>#colAttr#="#structFind(column,colAttr)#" </cfoutput></cfif>
|
||
</cfloop>>
|
||
<cfif len(column.field) AND column.sortable>
|
||
<c:order_arrows sortArray=#ATTRIBUTES.sortArray# n=#ATTRIBUTES.titleMap[column.field].ordinal#<!--- attributeCollection=#extraAttributes#--->/>
|
||
</cfif>
|
||
<cfif len(th.content)>
|
||
<cfset Evaluate("WriteOutput('#th.content#')")/>
|
||
<cfelseif len(column.field)>
|
||
<cfif structKeyExists(ATTRIBUTES.titleMap[column.field],"title")>
|
||
<cfoutput>#ATTRIBUTES.titleMap[column.field].title#</cfoutput>
|
||
</cfif>
|
||
</cfif>
|
||
</th>
|
||
</cfloop>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
<cfoutput query=#ATTRIBUTES.query# maxrows=#ATTRIBUTES.recordsPerPage# startrow=#ATTRIBUTES.nStart#>
|
||
<tr>
|
||
<cfloop array=#sortedColumns# index="column">
|
||
<cfset td=column.td[1]/>
|
||
<td<!--- Если нужно передать атрибут в TD, можно ввести тег <C:TD class="r"/> только как плейсхолдер для атрибутов, а поле будет получено от колонки --->
|
||
<cfloop collection=#td# item="tdAttr">
|
||
<cfif NOT listFindNoCase(tdAttributeList,tdAttr)>#tdAttr#="#structFind(td,tdAttr)#" </cfif>
|
||
</cfloop>
|
||
><cfif len(td.content)><cfset Evaluate("WriteOutput('#td.content#')")/><!---#td.content#--->
|
||
<cfelseif len(td.field)>#ATTRIBUTES.query[td.field][currentRow]#
|
||
<cfelseif len(column.field)>#column.formatter(ATTRIBUTES.query[column.field][currentRow])#
|
||
</cfif></td>
|
||
</cfloop>
|
||
</tr>
|
||
</cfoutput>
|
||
</tbody>
|
||
|
||
</table>
|
||
<!--- <cfdump var=#variables#/> --->
|
||
</cfif>
|
||
<!--- <cfexit method="exitTag"/> --->
|
||
|
||
<cfscript>
|
||
/**
|
||
* Sorts an array of structures based on a key in the structures.
|
||
*
|
||
* @param aofS Array of structures.
|
||
* @param key Key to sort by.
|
||
* @param sortOrder Order to sort by, asc or desc.
|
||
* @param sortType Text, textnocase, or numeric.
|
||
* @param delim Delimiter used for temporary data storage. Must not exist in data. Defaults to a period.
|
||
* @return Returns a sorted array.
|
||
* @author Nathan Dintenfass (nathan@changemedia.com)
|
||
* @version 1, December 10, 2001
|
||
*/
|
||
function arrayOfStructsSort(aOfS,key){
|
||
//by default we'll use an ascending sort
|
||
var sortOrder = "asc";
|
||
//by default, we'll use a textnocase sort
|
||
var sortType = "textnocase";
|
||
//by default, use ascii character 30 as the delim
|
||
var delim = ".";
|
||
//make an array to hold the sort stuff
|
||
var sortArray = arraynew(1);
|
||
//make an array to return
|
||
var returnArray = arraynew(1);
|
||
//grab the number of elements in the array (used in the loops)
|
||
var count = arrayLen(aOfS);
|
||
//make a variable to use in the loop
|
||
var ii = 1;
|
||
//if there is a 3rd argument, set the sortOrder
|
||
if(arraylen(arguments) GT 2)
|
||
sortOrder = arguments[3];
|
||
//if there is a 4th argument, set the sortType
|
||
if(arraylen(arguments) GT 3)
|
||
sortType = arguments[4];
|
||
//if there is a 5th argument, set the delim
|
||
if(arraylen(arguments) GT 4)
|
||
delim = arguments[5];
|
||
//loop over the array of structs, building the sortArray
|
||
for(ii = 1; ii lte count; ii = ii + 1)
|
||
sortArray[ii] = aOfS[ii][key] & delim & ii;
|
||
//now sort the array
|
||
arraySort(sortArray,sortType,sortOrder);
|
||
//now build the return array
|
||
for(ii = 1; ii lte count; ii = ii + 1)
|
||
returnArray[ii] = aOfS[listLast(sortArray[ii],delim)];
|
||
//return the array
|
||
return returnArray;
|
||
}
|
||
</cfscript> |