10 Replies Latest reply on Oct 1, 2014 8:36 AM by BKBK

    Problem with cfinput autosuggest and cfcomponent

    jackhuang

      I am new to using cfcomponent and autosuggest.  I followed the sample given in the Adobe Help Adobe ColdFusion 9 * Using Ajax User Interface Components and Features

       

      However, I am not getting the autosuggest to work at all.  This is what I did:

       

      1. I created a Suggestcfc.cfc under a subdirectory called "components"

      The Suggestcfc.cfc is as follows:

       

      <cfcomponent output="false">

          <cffunction name="getProduct" access="remote" returntype="array" output="false"> 

              <cfargument name="suggestvalue" required="true">

       

              <cfset var myarray = ArrayNew(1)>

       

          <cfquery datasource="mydatabase"  name="getlist">

          SELECT DISTINCT productname FROM products

              WHERE productname LIKE <cfqueryparam value="#suggestvalue#%" cfsqltype="cf_sql_varchar">

              </cfquery>

       

              <cfloop query="getlist">

                  <cfset arrayAppend(myarray, productname)>

              </cfloop>

              <cfreturn myarray>

          </cffunction>

         

          <cffunction name="init" output="false">

              <cfreturn this>

          </cffunction>

      </cfcomponent>

       

      2. I have a test.cfm as:

       

      <html xmlns="http://www.w3.org/1999/xhtml">

      <head>

      </head>

      <body>

      <cfset suggest = createObject("component", "components.Suggestcfc").init()>

      <cfform>

      <cfinput type="text" autosuggest="suggest.getProducts({cfautosuggestvalue})" name="string">

      </cfform>

      </body>

      </html>

       

      So when I run the test.cfm it only showed a box and when I started typing, nothing is being suggested (retrieve from the products table).  What am I doing wrong here?  Any help is appreciated.  Thanks in advance.

        • 1. Re: Problem with cfinput autosuggest and cfcomponent
          Carl Von Stetten Adobe Community Professional & MVP

          jackhuang,

           

          If you are a new user, I'd suggest you not go down the <CFFORM> and <CFINPUT> path.  It is fraught with peril!  All of the ColdFusion UI stuff (including <CFFORM> and <CFINPUT>) are built on outdated javascript libraries and do not implement all of the capabilities of those libraries.


          Rather, I suggest you learn a community-supported JavaScript library such as jQuery.  It provides fantastic AJAX support and has all the UI features you need, either as part of the core library, the related jQuery UI library, or the myriad of free plug-ins written by 3rd parties.  There are other libraries that offer similar functionality too: ExtJS (the CF UI stuff is mostly based on a really old version of ExtJS), Dojo, and several others.

           

          Many experienced developers have consciously moved away from using the built-in ColdFusion UI features due to compatibility issues and functional limitations.  Thus, you will be much less likely to get useful assistance with problems you encounter using those features.  On the other hand, the community-supported JavaScript libraries have a huge user base (both within and outside the ColdFusion community), and you will undoubtedly be able to get assistance with issues you may encounter.

           

          All of that said, after reviewing the docs, it looks like you need to change

          <cfinput type="text" autosuggest="suggest.getProducts({cfautosuggestvalue})" name="string">
          

           

          to

          <cfinput type="text" autosuggest="cfc:suggestcfc.getProducts({cfautosuggestvalue})" name="string">
          

           

          or possibly

          <cfinput type="text" autosuggest="cfc:components.suggestcfc.getProducts({cfautosuggestvalue})" name="string">
          

           

          Good luck,

          -Carl

          • 2. Re: Problem with cfinput autosuggest and cfcomponent
            jackhuang Level 1

            Thank you Carl.  The second one worked!  Now I have to figure out how to change the ugly blue color hovering over the list....

             

            I found that the list is pretty slow.  I also check the jQuery http://jqueryui.com/autocomplete/#remote  but found it extremely slow also.  Maybe it's the site. On top of that I do not know I can implement the above using code given there.

             

            I was looking at the twitter typahead at typeahead.js – examples  which look very promising and fast.  But again I don't know how to implement it together with the Coldfusion function that I have created above.

            • 3. Re: Problem with cfinput autosuggest and cfcomponent
              jackhuang Level 1

              Also I removed the line:

               

              <cfset suggest = createObject("component", "components.Suggestcfc").init()>

               

              and it still works.  Do I really need that line?  I am new to this object oriented programming.  Do I have to create the object every time the function is called?

              • 4. Re: Problem with cfinput autosuggest and cfcomponent
                Carl Von Stetten Adobe Community Professional & MVP

                You don't need the createObject(), since you are calling the component via AJAX (and not actually using the component on the actual page).

                 

                As far as performance, that has more to do with the general speed of your site and especially the code within your CFC.  What database platform are you using?  How well is it performing?  Is the table you are querying properly indexed?  Is the database running on the same server as ColdFusion, and does the server have adequate resources to perform (memory, processor speed/cores, etc.)?  The performance of <CFINPUT> versus jQuery, Bootstrap, or other autocompletes will likely be pretty similar to each other - it's mostly about how fast the data is transmitted and received from the server-side code via AJAX.

                 

                A couple other thoughts.  I notice you are using the LIKE operator in your query to do a wildcard search.  This is likely necessary for your query, but keep in mind that LIKE will always be slower than an equals comparison.

                 

                Also, instead of looping over the query results, take advantage of built-in functions to accomplish the same thing. So you could replace the entire loop with this:

                <cfset myarray = ListToArray( ValueList( getlist.ProductName ) )>

                 

                -Carl V.

                • 5. Re: Problem with cfinput autosuggest and cfcomponent
                  jackhuang Level 1

                  Thank you Carl.  These are very helpful.  Should I be indexing productname to make it "faster"?

                   

                  This is unrelated but in the pages where user have input I put:

                   

                     <cfset bad_chars="&,<,>,"",Æ,Á,Â,À,Å,Ã,Ä,Ç,Ð,É,Ê,È,Ë,Í,Î,Ì,Ï,Ñ,Ó,Ô,Ò,Ø,Õ,Ö,Þ,Ú,Û,Ù,Ü,Ý,á,â,æ,à,å ,ã,ä,ç,éê,è,ð,ë,í,î,ì,ï,ñ,ó,ô,ò,ø,õ,ö,ß,þ,ú,û,ù,ü,ý,ÿ,¡,£,¤,¥,¦,§,¨,©,ª,«,¬,,®,¯,°,±,²,³, ´,µ,¶,·,¸,¹,º,»,¼,½,¾,¿,×,÷,¢">
                     <cfset good_chars="&amp;,&lt;,&gt;,&quot;,&AElig;,&Aacute;,&Acirc;,&Agrave;,&Aring;,&Atilde;,&Au ml;,&Ccedil;,&ETH;,&Eacute;,&Ecirc;,&Egrave;,&Euml;,&Iacute;,&Icirc;,&Igrave;,&Iuml;,&Ntil de;,&Oacute;,&Ocirc;,&Ograve;,&Oslash;,&Otilde;,&Ouml;,&THORN;,&Uacute;,&Ucirc;,&Ugrave;,& Uuml;,&Yacute;,&aacute;,&acirc;,&aelig;,&agrave;,&aring;,&atilde;,&auml;,&ccedil;,&eacute; ,&ecirc;,&egrave;,&eth;,&euml;,&iacute;,&icirc;,&igrave;,&iuml;,&ntilde;,&oacute;,&ocirc;, &ograve;,&oslash;,&otilde;,&ouml;,&szlig;,&thorn;,&uacute;,&ucirc;,&ugrave;,&uuml;,&yacute ;,&yuml;,&iexcl;,&pound;,&curren;,&yen;,&brvbar;,&sect;,&uml;,&copy;,&ordf;,&laquo;,&not;, &shy;,&reg;,&macr;,&deg;,&plusmn;,&sup2;,&sup3;,&acute;&micro;,&para;,&middot;,&cedil;,&su p1;,&ordm;,&raquo;,&frac14;,&frac12;,&frac34;,&iquest;,&times;,&divide;,&cent;">
                     <cfset form.company = replacelist(form.company, bad_chars, good_chars)>
                     <cfset form.address = replacelist(form.address, bad_chars, good_chars)>
                     <cfset form.city = replacelist(form.city, bad_chars, good_chars)>....etc.

                   

                  to prevent bad inputs.  Is this the right/best way to do this as far as performance is concerned?

                  • 6. Re: Problem with cfinput autosuggest and cfcomponent
                    Carl Von Stetten Adobe Community Professional & MVP

                    Database indexes may not help with wildcard searches - they really only work in equals or not equals statements. What database are you using?  The last several versions of SQL Server support creating full-text indexes on database tables, and then allow you to use the full-text index to quickly search for words within a varchar or nvarchar column (somewhat similar to a LIKE wildcard statement, but performs better).

                     

                    "Bad inputs" is rather subjective, depending on context.  It looks like you are trying to replace extended ascii characters with their HTML entity counterparts.  There are already functions in ColdFusion that can do this for you.  For ColdFusion 10+, look at EncodeForHTML().

                     

                    -Carl V.

                    • 7. Re: Problem with cfinput autosuggest and cfcomponent
                      jackhuang Level 1

                      I am using MySql.

                       

                      The CF server version is 9 so there is no EncodeForHTML.  I have user who use some characters, I don't know what but could have been a Chinese punctuation mark. It some how include the > sign after a CFINPUT field and took the next <CFINPUT TYPE as part of the value.  So when I display the field which now has ><CFINPUT TYPE at the end. It really messes up the page and puts a input box right after the field.

                      • 8. Re: Problem with cfinput autosuggest and cfcomponent
                        BKBK Adobe Community Professional & MVP

                        Hi Jackhuang,

                        It appears Carl has answered your original question. So, please kindly mark the correct answer. It will help others in their search for answers to similar questions. Thank you.

                        • 9. Re: Problem with cfinput autosuggest and cfcomponent
                          Carl Von Stetten Adobe Community Professional & MVP

                          jackhuang,

                           

                          Take a look at the CF Backport project, which provides some CF10/11 functions for CF9 (and in some cases, CF8).  It includes a backport of EncodeForHTML().

                          -Carl V.

                          • 10. Re: Problem with cfinput autosuggest and cfcomponent
                            BKBK Adobe Community Professional & MVP

                            jackhuang wrote:

                             

                            This is unrelated but in the pages where user have input I put:

                             

                            <cfset bad_chars="&,<,>,"",Æ,Á,Â,À,Å,Ã,Ä,Ç,Ð,É,Ê,È,Ë,Í,Î,Ì,Ï,Ñ,Ó,Ô,Ò,Ø,Õ,Ö,Þ,Ú,Û,Ù,Ü,Ý,á,â,æ,à,å ,ã,ä,ç,éê,è,ð,ë,í,î,ì,ï,ñ,ó,ô,ò,ø,õ,ö,ß,þ,ú,û,ù,ü,ý,ÿ,¡,£,¤,¥,¦,§,¨,©,ª,«,¬,,®,¯,°,±,²,³, ´,µ,¶,·,¸,¹,º,»,¼,½,¾,¿,×,÷,¢">
                            <cfset good_chars="&amp;,&lt;,&gt;,&quot;,&AElig;,&Aacute;,&Acirc;,&Agrave;,&Aring;,&Atilde;,&Au ml;,&Ccedil;,&ETH;,&Eacute;,&Ecirc;,&Egrave;,&Euml;,&Iacute;,&Icirc;,&Igrave;,&Iuml;,&Nti l de;,&Oacute;,&Ocirc;,&Ograve;,&Oslash;,&Otilde;,&Ouml;,&THORN;,&Uacute;,&Ucirc;,&Ugrave;, & Uuml;,&Yacute;,&aacute;,&acirc;,&aelig;,&agrave;,&aring;,&atilde;,&auml;,&ccedil;,&eacute ; ,&ecirc;,&egrave;,&eth;,&euml;,&iacute;,&icirc;,&igrave;,&iuml;,&ntilde;,&oacute;,&ocirc; , &ograve;,&oslash;,&otilde;,&ouml;,&szlig;,&thorn;,&uacute;,&ucirc;,&ugrave;,&uuml;,&yacut e ;,&yuml;,&iexcl;,&pound;,&curren;,&yen;,&brvbar;,&sect;,&uml;,&copy;,&ordf;,&laquo;,&not; , &shy;,&reg;,&macr;,&deg;,&plusmn;,&sup2;,&sup3;,&acute;&micro;,&para;,&middot;,&cedil;,&s u p1;,&ordm;,&raquo;,&frac14;,&frac12;,&frac34;,&iquest;,&times;,&divide;,&cent;">
                            <cfset form.company = replacelist(form.company, bad_chars, good_chars)>
                            <cfset form.address = replacelist(form.address, bad_chars, good_chars)>
                            <cfset form.city = replacelist(form.city, bad_chars, good_chars)>....etc.

                             

                            to prevent bad inputs.  Is this the right/best way to do this as far as performance is concerned?

                            In my opinion, what you have to get right is the encoding. Use Unicode.

                             

                            You may be unable to edit this code in an editor that cannot display the characters in the bad_chars string. Use the characters' unicode value to make your code universal. Something like this

                             

                            <cfset char_unicode="38,60,62,34,198,193,194,192,197,195,196,199,208,201,202,200,203,205,206,204 ,207,209,211,212,210,216,213,214,222,218,219,217,220,221,225,226,230,224,229,227,228,231,2 33,232,240,235,237,238,236,239,241,243,244,242,248,245,246,223,254,250,251,249,252,253,255 ,161,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,32,181,182,183,184,18 5,186,187,188,189,190,191,215,247,162">

                            <cfset bad_chars = "">

                             

                            <cfloop list="#char_unicode#" index="u">

                                <cfset bad_chars = listAppend(bad_chars, chr(u))>

                            </cfloop>