181 lines
6.4 KiB
Plaintext
181 lines
6.4 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="guid">
|
|
<cfset element=trim(element)>
|
|
<cfif NOT isValid('guid',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>
|
|
|