Specify column of current item in query?

Apr 22, 2011 at 1:45 AM

Hey there...

I think this project will allow me to do what I need, however I'm having a problem figuring out the CAML I need to get this to work.

 My query is as follows:

<Where>
<Eq>
<FieldRef Name="LogoID" />
<Value Type="Text">XXXX</Value>
</Eq>
</Where>

However, I need XXXX to equal a value from a column in the current row but I don't know the syntax to do this.

Can someone point me in the right direction?

Coordinator
Apr 24, 2011 at 10:44 AM

Hi barbatto.
Currently, there's no way to do what you want.
The filtered lookup field does not support this feature, sorry.

Peppe

Oct 18, 2012 at 3:56 PM

I have "hacked" this by modifying the Util.cs file so that the query is run through a regular expression to parse out known tokens.  You can see the comments to see how to specify the tokens.

#region License
/*
http://sp2010filteredlookup.codeplex.com/
 
Copyright (c) 2010, Dev4Side
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of Dev4Side nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace IC.CTMO.Web.Core.CustomFields
{

    #region Util class

    internal sealed class Util
    {
        private static readonly Regex tokenPattern = new Regex(@"\$\$(\w+(\|\w+)?)\$\$");

        #region ListIsNullOrEmpty method

        /// <summary>
        ///     Indicates whether the specified generic list object is null or empty
        /// </summary>
        /// <param name = "list">A generic list</param>
        /// <returns>A value indicating whether the specified list object is null or empty</returns>
        internal static bool ListIsNullOrEmpty(List<ListItem> list)
        {
            return (list != null && list.Count > 0) ? false : true;
        }

        #endregion

        #region GetAvailableValues method

        internal static List<ListItem> GetAvailableValues(FilteredLookupField f, HttpContext ctx, SPListItem currentItem)
        {
            List<ListItem> _v = null;
            SPListItemCollection items = null;
            Guid fId = new Guid(f.LookupField);

            SPSite s = SPControl.GetContextSite(ctx);
            SPWeb lookupWeb = s.OpenWeb(f.LookupWebId);
            SPList lookupList = lookupWeb.Lists[new Guid(f.LookupList)];

            try
            {
                if (f.QueryFilter != null)
                {
                    SPQuery query = f.QueryFilter;

                    if(query.Query.IndexOf("$$") > 0)
                    {
                        // Replace tokens.
                        query.Query = ReplaceTokens(ctx, currentItem, query.Query);
                    }

                    items = lookupList.GetItems(query);
                }
            }
            catch {}

            if (items == null)
            {
                items = lookupList.Items;
            }

            if ((items != null && items.Count > 0))
            {
                _v = items
                    .Cast<SPListItem>()
                    .Where(e => e[fId] != null)
                    .Select(e => new ListItem((
                                                  e.Fields[fId].GetFieldValueAsText(e[fId])), e.ID.ToString()))
                    .ToList();
            }

            return _v;
        }

        
        /// <summary>
        /// Replaces the tokens in the query XML with the corresponding values from the current list item.
        /// 
        /// Tokens are specified as <c>$$propertyName|defaultValue$$</c>.  If the object does not have the specified property name, then the default value is used.
        /// </summary>
        /// <param name="currentItem">The current item.</param>
        /// <param name="query">The query.</param>
        /// <returns>The query with all tokens replaced.</returns>
        private static string ReplaceTokens(HttpContext ctx, SPListItem currentItem, string query)
        {            
            query = tokenPattern.Replace(query, delegate(Match match)
            {
                string propertyName = match.Groups[1].Value; // Gets the value without the $$...$$                

                if(currentItem == null)
                {
                    return match.Value;
                }

                string replacementValue = match.Value;

                bool useDefault = false;

                string[] parts = propertyName.Split('|');

                if (parts.Length > 0)
                {
                    propertyName = parts[0];
                }

                if(currentItem.Fields.ContainsFieldWithStaticName(propertyName))
                {
                    replacementValue = Convert.ToString(currentItem[propertyName]);

                    if (propertyName.Equals("FileDirRef") && string.IsNullOrEmpty(replacementValue) && ctx.Request != null)
                    {
                        replacementValue = ctx.Request["RootFolder"];
                    }

                    if (string.IsNullOrEmpty(replacementValue))
                    {
                        useDefault = true; // The value was empty; use the default value.
                    }
                }
                else
                {
                    useDefault = true; // Field doesn't exist; use the default value.
                }
                
                if(useDefault)
                {
                    // Return the default value.
                    if (parts.Length > 1)
                    {
                        replacementValue = parts[1];
                    }
                }

                return replacementValue;
            });

            return query;
        }

        /// <summary>
        /// Tokens the replacer.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <returns></returns>
        private static string TokenReplacer(Match match)
        {
            string token = match.Groups[1].Value;

            return "ASDF";
        }

        #endregion
    }

    #endregion

    #region Extensions class

    internal static class Extensions
    {
        // TO DO
        /// <summary>
        ///     Indicates whether a field in a list is associated with a SPFolder content type
        /// </summary>
        /// <param name = "field"></param>
        /// <returns></returns>
        internal static bool AssociatedWithFolder(this SPField field)
        {
            // THIS IS WORK IN PROGRESS
            if (field != null)
            {
                SPList list = field.ParentList;
            }

            return false;
        }
    }

    #endregion
}

Feb 5, 2013 at 7:16 AM
Hi CharlieDigital,

How do you pass the currentItem(SPListItem) object to the GetAvailableValues method from the FilteredLookupFieldControl & MultipleFilteredLookupFieldControl classes? Pls advice.