<% ' ============================================================================= ' stepsrch.asp ' Stepwise Search page ' ' Commerce Server 2000 Solution Sites 1.0 ' ----------------------------------------------------------------------------- ' This file is part of Microsoft Commerce Server 2000 ' ' Copyright (C) 2000 Microsoft Corporation. All rights reserved. ' ' This source code is intended only as a supplement to Microsoft ' Commerce Server 2000 and/or on-line documentation. See these other ' materials for detailed information regarding Microsoft code samples. ' ' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY ' KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ' IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A ' PARTICULAR PURPOSE. ' ============================================================================= Const LIST_LENGTH_THRESHOLD = 50 ' Max Number of Items to be displayed in Specification Search results list Const SEARCH_THRESHOLD = 5 ' Result set size in which products will be listed, rather than search being further refined Const CATALOG_PERFORM_SPEC_SEARCH_COLS = "CategoryName,Name,i_classtype" ' This page shows the search results whenever the number of ' returned matches is below or equal to set threshold, otherwise ' it indicate the size of result set only Sub Main() Dim oCatalog Dim sCatalogName, sCategoryName Dim sCacheKey, sSearchHandle Dim iMatchesFound Dim rsFields, rsResults Dim arr1() '--- Array of NonConstraining Searchable Properties Dim arr2() '--- Array of Constraining Searchable Properties Dim iConstraintFieldsCount, iNonConstraintFieldsCount Dim bViewResults, bNoValues, bClosestMatches 'Call EnsureAccess() ' Get CATEGORY Name sCategoryName = GetRequestString(DEF_NAME_URL_KEY, Null) If IsNull(sCategoryName) Then Response.Redirect(GenerateURL(MSCSSitePages.BadURL, Array(), Array())) End If ' Get CATALOG name and object sCatalogName = GetRequestString(CATALOG_NAME_URL_KEY, Null) Set oCatalog = GetCatalogForUser(sCatalogName, m_UserID) bViewResults = bClickedViewOrSearchButton() If bViewResults Then 'refined search, so we didn't cache the page Call PrepareSpecificationSearch(sCategoryName, sCatalogName, oCatalog, bViewResults, rsFields, rsResults, sSearchHandle, iMatchesFound, iConstraintFieldsCount, iNonConstraintFieldsCount, arr1, arr2, bNoValues, bClosestMatches) htmPageContent = htmRenderStepSearchPageContent(sCategoryName, sCatalogName, oCatalog, bViewResults, rsFields, rsResults, sSearchHandle, iMatchesFound, iConstraintFieldsCount, iNonConstraintFieldsCount, arr1, arr2, bNoValues, bClosestMatches) Else 'get the page from cache if it exists If Not bIsStepSearchPageCached(sCategoryName, sCatalogName, htmPageContent, sCacheKey) Then 'we didn't cache the page Call PrepareSpecificationSearch(sCategoryName, sCatalogName, oCatalog, bViewResults, rsFields, rsResults, sSearchHandle, iMatchesFound, iConstraintFieldsCount, iNonConstraintFieldsCount, arr1, arr2, bNoValues, bClosestMatches) htmPageContent = htmRenderStepSearchPageContent(sCategoryName, sCatalogName, oCatalog, bViewResults, rsFields, rsResults, sSearchHandle, iMatchesFound, iConstraintFieldsCount, iNonConstraintFieldsCount, arr1, arr2, bNoValues, bClosestMatches) Call CacheFragment("StepSearchPageCache", sCacheKey, htmPageContent) End If End If sPageTitle = mscsMessageManager.GetMessage("L_AdvancedSearch_HTMLTitle", sLanguage) End Sub ' ----------------------------------------------------------------------------- ' PrepareSpecificationSearch ' ' Description: ' Does a lot of the hard work. Fills in all passed parameters so the ' rendering functions know what to display. It fills in category name, ' catalog name, a recordset with fields, etc. ' ' Parameters: ' ' Returns: ' ' Notes : ' none ' ----------------------------------------------------------------------------- Sub PrepareSpecificationSearch(ByRef sCategoryName, ByRef sCatalogName, ByRef oCatalog, _ ByRef bViewResults, ByRef rsFields, ByRef rsResults, _ ByRef sSearchHandle, ByRef iMatchesFound, ByRef iConstraintFieldsCount, _ ByRef iNonConstraintFieldsCount, ByRef arr1, ByRef arr2, ByRef bNoValues, _ ByRef bClosestMatches) sSearchHandle = oCatalog.BeginSpecificationSearch(sCategoryName, rsFields, iMatchesFound) If Not (rsFields Is Nothing) Then ' Separate searchable fields into fields that add additional ' search constraint to the search clause and those that do not Call GetSpecificationSearchClauses (sSearchHandle, rsFields, oCatalog, arr1, arr2, _ iConstraintFieldsCount, iNonConstraintFieldsCount) ' Initialize variables bNoValues = True Call PerformSpecificationSearch (bViewResults, oCatalog, rsResults, rsFields, _ iMatchesFound, sSearchHandle, bClosestMatches) End If End Sub ' ----------------------------------------------------------------------------- ' bIsStepSearchPageCached ' ' Description: ' Is this page cached? If so, return the cached content in htmPageContent. ' Either way, return the cache key so that it can be used to cache the page ' if it wasn't cached already. ' ' Parameters: ' ' Returns: ' ' Notes : ' none ' ----------------------------------------------------------------------------- Function bIsStepSearchPageCached(sCategoryName, sCatalogName, ByRef htmPageContent, ByRef sCacheKey) sCacheKey = sCategoryName & ";_;" & sCatalogName htmPageContent = Null htmPageContent = LookupCachedFragment("StepSearchPageCache", sCacheKey) bIsStepSearchPageCached = Not(IsNull(htmPageContent)) End Function ' ----------------------------------------------------------------------------- ' bClickedViewButton ' ' Description: ' Check whether shopper clicked the "View" button to get here; i.e. ' Should we view the results? ' ' Parameters: ' ' Returns: ' True - success (yes, button was clicked) ' False - failure (no, it wasn't clicked) ' ' Notes : ' none ' ----------------------------------------------------------------------------- Function bClickedViewButton() If (mscsMessageManager.GetMessage("L_View_Search_Results_Button", sLanguage) = GetRequestString(ACTION_BTN_CTRL_NAME, Null)) Then bClickedViewButton = True Else bClickedViewButton = False End If End Function ' ----------------------------------------------------------------------------- ' bClickedViewOrSearchButton ' ' Description: ' Reached page by clicking View or Search, or not? ' ' Parameters: ' ' Returns: ' True - success (yes, one of those buttons was) ' False - failure (no, neither was clicked) ' ' Notes : ' none ' ----------------------------------------------------------------------------- Function bClickedViewOrSearchButton() If (mscsMessageManager.GetMessage("L_View_Search_Results_Button", sLanguage) = GetRequestString(ACTION_BTN_CTRL_NAME, Null)) Or _ (mscsMessageManager.GetMessage("L_Search_Button", sLanguage) = GetRequestString(ACTION_BTN_CTRL_NAME, Null)) Then bClickedViewOrSearchButton = True Else'Page Back (<-) bClickedViewOrSearchButton = False End If End Function ' ----------------------------------------------------------------------------- ' GetSpecificationSearchClauses ' ' Description: ' Helper business logic function to generate the proper search clauses ' ' Parameters: ' ' Returns: ' ' Notes : ' none ' ----------------------------------------------------------------------------- Sub GetSpecificationSearchClauses(ByRef sSearchHandle, ByRef rsFields, ByRef oCatalog, _ ByRef arr1, Byref arr2, ByRef iConstraintFieldsCount, ByRef iNonConstraintFieldsCount) Dim bQuote Dim sValue Dim objField Dim iFieldType Dim sSearchClause Dim sPropertyName ' Initialize variables iConstraintFieldsCount = 0 iNonConstraintFieldsCount = 0 ReDim arr1(rsFields.Fields.Count) ReDim arr2(rsFields.Fields.Count) For Each objField In rsFields.Fields sValue = GetRequestString(objField.Name, mscsMessageManager.GetMessage("L_STEPSEARCH_NO_PREFERENCE_TEXT", sLanguage)) If sValue = mscsMessageManager.GetMessage("L_STEPSEARCH_NO_PREFERENCE_TEXT", sLanguage) Then ' Field is not a search constraint arr1(iNonConstraintFieldsCount) = objField.Name iNonConstraintFieldsCount = iNonConstraintFieldsCount + 1 Else ' Field is a Search Constraint sPropertyName = objField.Name arr2(iConstraintFieldsCount) = sPropertyName ' Lookup the property's DataType attribute from property attributes cache. iFieldType = MSCSCatalogAttribs.Value(sPropertyName).Value("DataType") If (iFieldType = cscString) Or _ (iFieldType = cscDateTime) Or _ (iFieldType = cscFilePath) Or _ (iFieldType = cscEnumeration) Then ' If Text OR DateTime OR FilePath OR Multiple Choice bQuote = True Else bQuote = False End If sSearchClause = "" For Each sValue In Request.Form(sPropertyName) If bQuote Then sValue = """" & sValue & """" sSearchClause = sSearchClause & ", " & sValue Next ' Add Specification Search Clause sSearchClause = "[" & sPropertyName & "]" & _ " IN (" & _ Right(sSearchClause, Len(sSearchClause) - 2) & _ ")" Call oCatalog.AddSpecificationSearchClause(sSearchClause, sSearchHandle) iConstraintFieldsCount = iConstraintFieldsCount + 1 End If Next ReDim Preserve arr1(iNonConstraintFieldsCount) ReDim Preserve arr2(iConstraintFieldsCount) End Sub ' ----------------------------------------------------------------------------- ' PerformSpecificationSearch ' ' Description: ' Helper business logic sub to perform the search ' ' Parameters: ' ' Returns: ' ' Notes : ' none ' ----------------------------------------------------------------------------- Sub PerformSpecificationSearch(ByRef bViewResults, ByRef oCatalog, ByRef rsResults, _ ByRef rsFields, ByRef iMatchesFound, ByVal sSearchHandle, ByRef bClosestMatches) Dim rs Dim sColList Dim iSearchType bClosestMatches = False iSearchType = cscProductClass + cscProductFamilyClass If (bViewResults = True) Or (iMatchesFound <= SEARCH_THRESHOLD) Then sColList = CATALOG_PERFORM_SPEC_SEARCH_COLS If (oCatalog.IdentifyingProductProperty <> PRODUCT_NAME_PROPERTY_NAME) Then sColList = sColList + "," + oCatalog.IdentifyingProductProperty End If bViewResults = bClickedViewButton() If bViewResults Then rs = NULL Else Set rs = rsFields End If Set rsResults = oCatalog.PerformSpecificationSearch(sSearchHandle, iSearchType, , iMatchesFound, rs, sColList) If (True = rsResults.EOF) Then Set rsResults = oCatalog.GuaranteedSpecificationSearch(sSearchHandle, iSearchType, , iMatchesFound, rs, sColList) bViewResults = True bClosestMatches = True End If End If End Sub ' ----------------------------------------------------------------------------- ' Rendering functions ' ----------------------------------------------------------------------------- ' ----------------------------------------------------------------------------- ' htmRenderStepSearchPageContent ' ' Description: ' Render the results ' ' Parameters: ' ' Returns: ' ' Notes : ' none ' ----------------------------------------------------------------------------- Function htmRenderStepSearchPageContent (sCategoryName, sCatalogName, ByRef oCatalog, _ bViewResults, ByRef rsFields, ByRef rsResults, sSearchHandle, iMatchesFound, _ iConstraintFieldsCount, iNonConstraintFieldsCount, _ arr1, arr2, bNoValues, bClosestMatches) Dim htmTitle, htmContent htmTitle = RenderText(mscsMessageManager.GetMessage("L_AdvancedSearch_HTMLTitle", sLanguage), MSCSSiteStyle.Title) & CRLF htmContent = RenderText(mscsMessageManager.GetMessage("L_STEPSEARCH_PRODUCT_GROUP_TEXT", sLanguage) _ & " " & sCategoryName, MSCSSiteStyle.Body) & CR If (rsFields Is Nothing) Then htmContent = RenderText(mscsMessageManager.GetMessage("L_No_Searchable_Properties_HTMLText", sLanguage), _ MSCSSiteStyle.Body) & CRLF Else If bClosestMatches Then htmContent = htmContent & RenderText(mscsMessageManager.GetMessage("L_Closest_Matches_Found_HTMLText", sLanguage), MSCSSiteStyle.Body) & CRLF End If If (iMatchesFound > SEARCH_THRESHOLD) And (iNonConstraintFieldsCount > 0) And _ (bViewResults = False) Then Call ShowRefinedSearch (sCatalogName, sCategoryName, rsFields, arr1, arr2, _ iMatchesFound, iConstraintFieldsCount, _ iNonConstraintFieldsCount, bNoValues, htmContent) End If If (iMatchesFound <= SEARCH_THRESHOLD) Or (iNonConstraintFieldsCount = 0) Or _ (bNoValues = True) Or (bViewResults = True) Then Call ShowSearchMatches (oCatalog, rsResults, iMatchesFound, htmContent) End If End If ' Return Page Content htmRenderStepSearchPageContent = htmTitle & htmContent End Function ' ----------------------------------------------------------------------------- ' ShowRefinedSearch ' ' Description: ' ' Parameters: ' ' Returns: ' ' Notes : ' none ' ----------------------------------------------------------------------------- Sub ShowRefinedSearch(ByRef sCatalogName, ByRef sCategoryName, ByRef rsFields, ByRef arr1, _ ByRef arr2, ByVal iMatchesFound, ByVal iConstraintFieldsCount, _ ByVal iNonConstraintFieldsCount, ByRef bNoValues, ByRef htmContent) Dim i, j Dim iFieldType Dim iItemsCount Dim urlPost Dim arrItems Dim sListBoxName, sBtnSearch, sBtnView, sSelectedOption, iSize, bMultiple Dim htmFormContent bMultiple = True For i = 0 To iNonConstraintFieldsCount - 1 sListBoxName = arr1(i) Call RemoveBlankItemsFromArray(rsFields.Fields(arr1(i)).Value, arrItems) iItemsCount = UBound(arrItems) + 1 ' Lookup the property's DataType attribute from property attributes cache. iFieldType = MSCSCatalogAttribs.Value(arr1(i)).Value("DataType") 'Response.Write "
  • " & ifieldtype 'Response.end on error resume next Select Case iFieldType Case cscBoolean ' Boolean For j = 0 To iItemsCount - 1 arrItems(j) = BooleanToString(arrItems(j)) Next Case cscInteger, cscCurrency, _ cscDateTime, cscString ' Integer, Money, Date, String End Select If (iItemsCount > 0) Then bNoValues = False htmFormContent = htmFormContent & RenderText(sListBoxName, _ MSCSSiteStyle.Body) & CR ' Add a NO PREFERENCE entry ReDim Preserve arrItems(iItemsCount) arrItems(iItemsCount) = mscsMessageManager.GetMessage("L_STEPSEARCH_NO_PREFERENCE_TEXT", sLanguage) sSelectedOption = mscsMessageManager.GetMessage("L_STEPSEARCH_NO_PREFERENCE_TEXT", sLanguage) iSize = iItemsCount + 1 htmFormContent = htmFormContent & RenderListBoxFromArray(sListBoxName, arrItems, arrItems, sSelectedOption, iSize, bMultiple, MSCSSiteStyle.ListBox) & CRLF End If Next If (iConstraintFieldsCount > 0) Then bNoValues = False htmContent = htmContent & RenderText(_ mscsMessageManager.GetMessage("L_STEPSEARCH_CONSTRAINTS_FIELDS_TEXT", sLanguage), _ MSCSSiteStyle.Body) & CR For i = 0 To iConstraintFieldsCount - 1 ' Lookup the property's DataType attribute from property attributes cache. iFieldType = MSCSCatalogAttribs.Value(arr2(i)).Value("DataType") Select Case iFieldType Case cscBoolean ' Boolean htmContent = htmContent & _ RenderText(arr2(i) & ": " & _ BooleanToString(GetRequestString(arr2(i), Null)), _ MSCSSiteStyle.Body) & CR Case cscInteger, cscFloat, cscCurrency, _ cscDateTime, cscString, cscEnumeration ' Integer, Money, Date, String htmContent = htmContent & _ RenderText(arr2(i) & ": " & _ GetRequestString(arr2(i), Null), _ MSCSSiteStyle.Body) & CR End Select htmFormContent = htmFormContent & _ RenderHiddenField(arr2(i), _ GetRequestString(arr2(i), Null) _ ) Next End If If (bNoValues = False) Then sBtnSearch = mscsMessageManager.GetMessage("L_Search_Button", sLanguage) sBtnView = mscsMessageManager.GetMessage("L_View_Search_Results_Button", sLanguage) htmFormContent = htmContent & _ RenderText(mscsMessageManager.GetMessage("L_STEPSEARCH_MATCHES_FOUND_TEXT", sLanguage) _ & " " & iMatchesFound, MSCSSiteStyle.Body) & _ Space(8) & _ RenderSubmitButton(ACTION_BTN_CTRL_NAME, sBtnSearch, MSCSSiteStyle.Button) & Space(2) & _ RenderSubmitButton(ACTION_BTN_CTRL_NAME, sBtnView, MSCSSiteStyle.Button) & CRLF & _ RenderText(mscsMessageManager.GetMessage("L_STEPSEARCH_NARROW_DOWN_TEXT", sLanguage), MSCSSiteStyle.Body) & CRLF & _ htmFormContent htmFormContent = htmFormContent & _ RenderHiddenField(DEF_NAME_URL_KEY, sCategoryName) htmFormContent = htmFormContent & RenderHiddenField(CATALOG_NAME_URL_KEY, sCatalogName) urlPost = GenerateURL(MSCSSitePages.StepSearch, Array(), Array()) htmContent = RenderForm(urlPost, htmFormContent, HTTP_POST) End If End Sub ' ----------------------------------------------------------------------------- ' ShowSearchMatches ' ' Description: ' ' Parameters: ' ' Returns: ' ' Notes : ' none ' ----------------------------------------------------------------------------- Sub ShowSearchMatches(ByRef oCatalog, ByRef rsResults, ByVal iMatchesFound, ByRef htmContent) Dim i Dim iLength htmContent = htmContent & _ RenderText(mscsMessageManager.GetMessage("L_STEPSEARCH_MATCHES_RETURNED_TEXT", sLanguage) & _ iMatchesFound, MSCSSiteStyle.Body) & CRLF If (iMatchesFound > LIST_LENGTH_THRESHOLD) Then ' Truncate List of Items if it exceeds LIST_LENGTH_THRESHOLD iLength = LIST_LENGTH_THRESHOLD - 1 htmContent = htmContent & _ RenderText(mscsMessageManager.GetMessage("L_STEPSEARCH_TRUNCATED_LIST_TEXT", sLanguage), MSCSSiteStyle.Body) & CRLF Else iLength = iMatchesFound - 1 End If For i = 0 To iLength Select Case rsResults(PROD_CLASSTYPE_FLDNAME) Case cscCategoryClass htmContent = htmContent & _ RenderCategoryLink(rsResults(PROD_CATALOG_FLDNAME).Value, _ rsResults(CATEGORY_NAME_PROPERTY_NAME).Value, _ 1, _ MSCSSiteStyle.Body) & CR Case cscProductClass, cscProductFamilyClass ' "name" is a required product property and cannot have null value. htmContent = htmContent & _ RenderProductLink(rsResults(PROD_CATALOG_FLDNAME).Value, _ CATALOG_SEARCH_CATEGORY_NAME, _ rsResults(PRODUCT_NAME_PROPERTY_NAME).Value, _ rsResults(oCatalog.IdentifyingProductProperty).Value, _ MSCSSiteStyle.Body) & CR End Select rsResults.MoveNext Next End Sub %>