{"id":888,"date":"2006-12-08T23:32:57","date_gmt":"2006-12-09T07:32:57","guid":{"rendered":"http:\/\/cephas.net\/blog\/2006\/12\/08\/scriptaculous-autocompleter-elementcollecttextnodes-and-elementcleanwhitespace\/"},"modified":"2006-12-08T23:36:54","modified_gmt":"2006-12-09T07:36:54","slug":"scriptaculous-autocompleter-elementcollecttextnodes-and-elementcleanwhitespace","status":"publish","type":"post","link":"https:\/\/cephas.net\/blog\/2006\/12\/08\/scriptaculous-autocompleter-elementcollecttextnodes-and-elementcleanwhitespace\/","title":{"rendered":"Script.aculous, Autocompleter, Element.collectTextNodes and Element.cleanWhitespace"},"content":{"rendered":"<p>A couple days ago I was fighting with the <a href=\"http:\/\/wiki.script.aculo.us\/scriptaculous\/show\/Autocompletion\">Script.aculous autocompleter<\/a>. I was using code that was almost exactly like the <a href=\"http:\/\/demo.script.aculo.us\/ajax\/autocompleter_customized\">customized autocompletion demo<\/a>, where the  content returned from the AJAX call was a bulleted list of items with each item containing three div&#8217;s:<\/p>\n<pre>\r\n&lt;ul id=\"mylist\"&gt;\r\n  &lt;li&gt;\r\n    &lt;div&gt;&lt;img src=\"\/images\/avatar\/robot.png\" \/&gt;&lt;\/div&gt;\r\n    &lt;div&gt;Aaron Johnson&lt;\/div&gt;\r\n  &lt;\/li&gt;\r\n  &lt;li&gt;\r\n  ...\r\n  &lt;\/li&gt;\r\n&lt;\/ul&gt;\r\n<\/pre>\n<p>After the content is returned, the user selects an option and the &#8216;updateElement()&#8217; function of <a href=\"http:\/\/wiki.script.aculo.us\/scriptaculous\/show\/Autocompleter.Base\">Autocompleter.Base<\/a> is called, which itself uses a function &#8216;Element.collectTextNodes()&#8217;.  Element.collectTextNodes traverses the all the nodes in the selected option and retrieves the text value of each one, effectively stripping the HTML from the ul element. Finally, the autocompleter takes the resulting text value and updates the value of the textbox that you started with in the first place. <\/p>\n<p>At least that&#8217;s what&#8217;s supposed to happen. What actually happened was that the textbox wasn&#8217;t showing the selected value at all and I beat my head against my desk a couple times.  Why? If you take the HTML example above and run it through Element.collectTextNodes(), you&#8217;ll get this:<\/p>\n<pre>\r\n\r\nAaron Johnson\r\n<\/pre>\n<p>not this:<\/p>\n<pre>\r\nAaron Johnson\r\n<\/pre>\n<p>See the line break?  If you try to update the value of a textbox with a variable whose first line is a line break, the textbox sees only the line break and nothing else. <\/p>\n<p>The solution turns out to be a widely used function in prototype: <a href=\"http:\/\/wiki.script.aculo.us\/scriptaculous\/show\/Element.cleanWhitespace\">Element.cleanWhitespace()<\/a>, which removes all empty text node children of an element.  So I updated Element.collectTextNodes to look like this:<\/p>\n<pre>\r\nElement.collectTextNodes = function(element) {\r\n  element = Element.cleanWhitespace(element);\r\n  return $A($(element).childNodes).collect( function(node) {\r\n    return (node.nodeType==3 ? node.nodeValue :\r\n      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));\r\n  }).flatten().join('');\r\n}\r\n<\/pre>\n<p>I created a <a href=\"http:\/\/wiki.script.aculo.us\/scriptaculous\/show\/Element.collectTextNodes\">wiki page<\/a> on the <a href=\"http:\/\/wiki.script.aculo.us\/scriptaculous\/\">script.aculous wiki<\/a> for the Element.collectTextNodes function, post a comment on the wiki if you agree that the function should include a call to Element.cleanWhitespace. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>A couple days ago I was fighting with the Script.aculous autocompleter. I was using code that was almost exactly like the customized autocompletion demo, where the content returned from the AJAX call was a bulleted list of items with each item containing three div&#8217;s: &lt;ul id=&#8221;mylist&#8221;&gt; &lt;li&gt; &lt;div&gt;&lt;img src=&#8221;\/images\/avatar\/robot.png&#8221; \/&gt;&lt;\/div&gt; &lt;div&gt;Aaron Johnson&lt;\/div&gt; &lt;\/li&gt; &lt;li&gt; &#8230; &hellip; <a href=\"https:\/\/cephas.net\/blog\/2006\/12\/08\/scriptaculous-autocompleter-elementcollecttextnodes-and-elementcleanwhitespace\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Script.aculous, Autocompleter, Element.collectTextNodes and Element.cleanWhitespace<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[29],"tags":[],"_links":{"self":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts\/888"}],"collection":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/comments?post=888"}],"version-history":[{"count":0,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts\/888\/revisions"}],"wp:attachment":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/media?parent=888"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/categories?post=888"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/tags?post=888"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}