174 lines
6.3 KiB
Plaintext
174 lines
6.3 KiB
Plaintext
<!--- version 2.01---><!---15:25 31.01.2019--->
|
||
<!--- 2017.06.16 исправлен баг с очисткой при числовом значении по умолчанию --->
|
||
<!---v0.5 10:02 02.01.2019--->
|
||
<cfassociate basetag="cf_filter_settings"/>
|
||
<cfparam name="ATTRIBUTES.filter" type="struct" default=#getBaseTagData("CF_FILTER_SETTINGS",1).filter#/><!--- *** possible Railo bug, getBaseTagData works only with second parameter --->
|
||
<cfparam name="ATTRIBUTES.param" type="string"/>
|
||
<cfparam name="ATTRIBUTES.default" type="string" default=""/><!--- список: значения, установленные по умолчанию. Обычно состоит из 1 значения даже для списка. В случае кодирования base64 этот список НЕ кодируется (проблемы с запятыми остаются на совести разработчика)--->
|
||
<!---*** И вообще Base64 нельзя использовать непосредственно, он не URLsafe --->
|
||
<cfparam name="ATTRIBUTES.ftype" type="string" default="string"/>
|
||
<cfparam name="ATTRIBUTES.list" type="boolean" default="No"/>
|
||
<cfparam name="ATTRIBUTES.compare" type="string" default="EQ"/>
|
||
<cfparam name="ATTRIBUTES.field" type="string" default=""/>
|
||
<cfparam name="ATTRIBUTES.base64" type="boolean" default="No"/><!--- означает, что параметр нужно раскодировать из base64---><!---*** Переделать на URL-safe base64--->
|
||
|
||
<!---
|
||
CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" ставит апострофы вокруг значения параметра.
|
||
Поэтому приходится любые wildcards засовывать в значение bind variable. Запрос должен иметь вид
|
||
SELECT A,B FROM C WHERE A LIKE ?
|
||
(без всяких апострофов), а значение параметра будет, например,
|
||
"%#submitted_string#%"
|
||
--->
|
||
<cfparam name="ATTRIBUTES.prefix" type="string" default=""/>
|
||
<cfparam name="ATTRIBUTES.suffix" type="string" default=""/>
|
||
<cfparam name="ATTRIBUTES.expression" type="string" default=""/>
|
||
|
||
<!---
|
||
Хранение данных для списков
|
||
переделано обратно с массива на лист.
|
||
При этом случилась забавная, но неприятная и трудноуловимая ошибка
|
||
arrayAppend(array,item) механически заменил на listAppend(list,item)
|
||
а надо было на list=listAppend(list,item)
|
||
--->
|
||
|
||
<!---<cfif ATTRIBUTES.list>
|
||
<cfset def = "">
|
||
<cfloop list=#ATTRIBUTES.default# index="item">
|
||
<cfset listAppend(def, item)>Список значений по умолчанию НЕ должен быть кодирован в base64 при ATTRIBUTES.base64
|
||
</cfloop>
|
||
<cfelse>
|
||
|
||
</cfif>--->
|
||
<cfset def=ATTRIBUTES.default/>
|
||
<!---<cfoutput>#ATTRIBUTES.param#:</cfoutput>--->
|
||
|
||
<!---<cfif evaluate("isDefined('CALLER.#ATTRIBUTES.param#')")>
|
||
<cfset evaluate("val=(CALLER.#ATTRIBUTES.param#)")>--->
|
||
|
||
<cfif structKeyExists(CALLER, '#ATTRIBUTES.param#')>
|
||
<cfset val=structFind(CALLER, '#ATTRIBUTES.param#')/>
|
||
<!--- parse --->
|
||
|
||
<cfset to=1/>
|
||
<cfset values = ""/>
|
||
|
||
<cfif ATTRIBUTES.list>
|
||
<cfset to=listLen(val)/>
|
||
|
||
</cfif>
|
||
|
||
<cfloop from="1" to=#to# index="i">
|
||
|
||
<cfif ATTRIBUTES.list>
|
||
<cfset element=listGetAt(val,i)/>
|
||
<cfelse>
|
||
<cfset element=val/>
|
||
</cfif>
|
||
|
||
<cfswitch expression=#ATTRIBUTES.ftype#>
|
||
|
||
<cfcase value="numeric">
|
||
<cfset element=trim(element)>
|
||
<cfif NOT isNumeric(element)>
|
||
<cfset element=def/>
|
||
</cfif>
|
||
</cfcase>
|
||
|
||
<cfcase value="date">
|
||
<cftry>
|
||
<cfset element=CreateDateTime(ListGetAt(element,3,'.'), ListGetAt(element,2,'.'), ListGetAt(element,1,'.'),0,0,0)>
|
||
<cfcatch type="Any">
|
||
<!--- <cfoutput>#cfcatch.message# #cfcatch.detail#</cfoutput> --->
|
||
</cfcatch>
|
||
</cftry>
|
||
</cfcase>
|
||
|
||
<cfcase value="string">
|
||
<cfif ATTRIBUTES.base64>
|
||
<cfset element=ToString(BinaryDecode(element , "base64"))>
|
||
</cfif>
|
||
<cfset element=safeStr(element)/>
|
||
</cfcase>
|
||
|
||
<cfdefaultcase>
|
||
<cfthrow message="Filterparam: unsupported ftype value '#ATTRIBUTES.ftype#'" detail="Supported values are 'numeric', 'date', 'string'">
|
||
</cfdefaultcase>
|
||
|
||
</cfswitch>
|
||
|
||
<cfif ATTRIBUTES.list>
|
||
<cfset values=listAppend(values, element)/>
|
||
<cfelse>
|
||
<cfset val=element/>
|
||
<cfbreak/>
|
||
</cfif>
|
||
|
||
</cfloop>
|
||
|
||
<cfif ATTRIBUTES.list>
|
||
<cfset val=values/><!---*** все это выглядит ужасно. Переиспользование переменных вперед-назад, IF вокруг листа--->
|
||
</cfif>
|
||
|
||
<!---/parse --->
|
||
|
||
<cfelseif structKeyExists(ATTRIBUTES.filter, ATTRIBUTES.param)><!--- если параметр есть в сохраненном фильтре, взять оттуда --->
|
||
|
||
<cfset filterItem = structFind(ATTRIBUTES.filter, ATTRIBUTES.param)>
|
||
<cfif isStruct(filterItem)>
|
||
<cfset val=filterItem.val>
|
||
<cfelse><!---not struct <cfoutput>#ATTRIBUTES.param#</cfoutput>--->
|
||
<cfset val=def>
|
||
</cfif>
|
||
|
||
<cfelse>
|
||
|
||
<cfset val=def>
|
||
|
||
</cfif>
|
||
|
||
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.param#", "")/>
|
||
<cftry>
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.param#",#val#)/>
|
||
<cfcatch type="Any"></cfcatch>
|
||
</cftry>
|
||
|
||
|
||
<cfif shouldRemoveValue(val, def)>
|
||
<cfset structDelete(ATTRIBUTES.filter, ATTRIBUTES.param)/>
|
||
<cfelse>
|
||
<cfset fltItem=structNew()>
|
||
<cfset fltItem.ftype=ATTRIBUTES.ftype>
|
||
<cfset fltItem.list=ATTRIBUTES.list>
|
||
<cfset fltItem.field=ATTRIBUTES.field>
|
||
<cfset fltItem.compare=ATTRIBUTES.compare>
|
||
<cfset fltItem.val=val>
|
||
<cfset fltItem.prefix=ATTRIBUTES.prefix/>
|
||
<cfset fltItem.suffix=ATTRIBUTES.suffix/>
|
||
<cfset fltItem.expression=ATTRIBUTES.expression/>
|
||
<cfset structInsert(ATTRIBUTES.filter,ATTRIBUTES.param,fltItem, "TRUE")>
|
||
</cfif>
|
||
|
||
<cfexit method="exittag"/>
|
||
|
||
<cffunction name="shouldRemoveValue" returnType="boolean">
|
||
<cfargument name="val"/>
|
||
<cfargument name="def"/>
|
||
<!---<cfdump var=#val#> <cfdump var=#def#>--->
|
||
<cfscript>
|
||
if (!IsSimpleValue(val)){
|
||
if (isArray(val)) {
|
||
return (arrayLen(val) == 0);
|
||
}
|
||
return false;
|
||
}
|
||
return ((val==def) OR (val==""));
|
||
</cfscript>
|
||
</cffunction>
|
||
|
||
<cffunction name="safeStr" returnType="string">
|
||
<cfargument name="val" type="string"/>
|
||
<cfreturn replaceList(val, "',"",<,>", ",,,")/>
|
||
</cffunction>
|
||
|