Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member184549
Participant
0 Kudos

In a recent SAP CRM 2007 implementation, we had the requirement to hide a view (“partial”) in response to a change in a dropdown value.<!-- Begin C11_W43_V44_V48 ><br /><div id="C1_W1_V2_C1_W1_V2_V3_C11_W43_V44_C11_<br />W43_V44_V48_productdetailviewset.do" class="th-ajax-area"><br /><! Begin C1_W1_V2_C1_W1_V2_V3_C11_W43_V44_C11_
W43_V44_V48_productdetailviewset.do ><br /><table ....<br /></pre><p> </p><p>The element we’re interested in hiding is the div with id=“C1_W1_V2_C1_W1_V2_V3_C11_W43_V44_C11_W43_V44_V48_productdetailviewset.do” </p><p>In it’s simplest case, the following javascript, if inserted into the view somewhere after the thtmlb:gridCell tag that declares dropdown element B, does what is required – it will hide block A if the value of dropdown B changes to anything other than “Corporate Brands”:</p><pre><script for="ClassificationDdlb1" event=onchange type="text/javascript"><br />var dd = document.getElementById("C14_W59_V60_ClassificationDdlb1");<br />var hidee = document.getElementById(</pre><pre>"C1_W1_V2_C1_W1_V2_V3_C11_W43_V44_C11_W43_V44_V48_productdetailviewset.do");<br />if(dd.value != "Corporate Brands"){<br />  hidee.style.display = 'none';<br />}<br />else {<br />  hidee.style.display = 'inline';<br />}<br /></script><br /></pre><pre><br /> </pre><p> </p><p> </p><p>Of course, we’re going to require something a little more complicated! The problem is that the id for the elements under consideration is not fixed – the C14_W59_V60 will be different for different roles and is affected by configuration changes. One way to solve this problem is to write a javascript function that will go through all elements and check for a regular expression match based on the contents of id. However the javascript function getElementById only accepts an exact match on id.</p><p>A custom function fuzzyElementSearch was created to find the element of interest (this function is contained within the file jonathan.js which will be listed afterwards), this is what the call to this function looks like:</p><pre><script src="/sap/bc/bsp/sap/crmcmp_ic_frame/scripts/common/jonathan.js" type="text/javascript"><br /></script><br /><script for="ClassificationDdlb1" event=onchange type="text/javascript"><br /><br />var dd       = fuzzyElementSearch("th-ip-td1","td",null,"input","ClassificationDdlb1", 0)[0];<br />var dd2      = dd[0];<br />var hide     = fuzzyElementSearch("th-gr-td","td", null, "div","productdetailviewset", 1)[0];<br />if ((hide) && (dd2) && (hide.length > 0)) {<br />  var hide2    = hide[0];<br /><br />  if ((dd2.value) != "Corporate Brands") {<br />    hide2.style.display = 'none';<br />  }<br />  else {<br />    hide2.style.display = 'inline';<br />  }<br />}<br /><br /></script><br /></pre><pre><br /> </pre><p>The file jonathan.js contains the following javascript:-</p><pre>function fuzzyElementSearch(classname, tagname, root, tag2, subbie, level) {<br /><br />    // Call function from Rhino book that returns<br />    // an array of DOM elements that are members of the specified class,<br />    // have the specified tagname, and are descendants of the specified root.<br />    var elements = getElements(classname, tagname, root);<br /><br />    // Find children (of tag2) for each of these elements<br />    var subfound = [];<br /><br />    for(var i = 0; i < elements.length; i+) {<br />        var subchild  = elements[i];<br />        var grandkids = subchild.getElementsByTagName(tag2);<br />        if (grandkids) subfound.push(grandkids);<br />    }<br /><br />    // search "level" deep for each of the above matches<br />    // for an element where the id contains the substring<br />    var pattern = new RegExp(subbie, "g");<br />    var matches = [];<br />    for(var i = 0; i < subfound.length; i) {<br />        var matchee  = subfound[i];<br />        if (matchee.length > level) {<br />          var matchin = matchee[level];<br />          var matchid = matchin.id;<br />          var reslt = pattern.test(matchid);<br />          if(reslt == true) {<br />             matches.push(matchee);<br />          }<br />        }<br />    }<br /><br />    // Note that we always return an array, even if it is empty<br />    return matches;</pre><pre><br /><br /><br /> // *** The following attribution applies to the rest of the code in this file<br /> // This code is from the book JavaScript: The Definitive Guide, 5th Edition,<br /> // by David Flanagan. Copyright 2006 O'Reilly Media, Inc. (ISBN #0596101996)<br /> // *** <br /><br /> /* Rest of code == EXAMPLE 15-4 From David Flanagan, "Javascript"<br /> * getElements(classname, tagname, root):<br /> * Return an array of DOM elements that are members of the specified class,<br /> * have the specified tagname, and are descendants of the specified root.<br /> *<br /> * If no classname is specified, elements are returned regardless of class.<br /> * If no tagname is specified, elements are returned regardless of tagname.<br /> * If no root is specified, the document object is used.  If the specified<br /> * root is a string, it is an element id, and the root<br /> * element is looked up using getElementsById()<br /> /<br />    function getElements(classname, tagname, root) {<br />        // If no root was specified, use the entire document<br />        // If a string was specified, look it up<br />        if (!root) root = document;<br />        else if (typeof root == "string") root = document.getElementById(root);<br /><br />        // if no tagname was specified, use all tags<br />        if (!tagname) tagname = "";<br /><br />        // Find all descendants of the specified root with the specified tagname<br />        var all = root.getElementsByTagName(tagname);<br /><br />        // If no classname was specified, we return all tags<br />        if (!classname) return all;<br /><br />        // Otherwise, we filter the element by classname<br />        var elements = [];  // Start with an emtpy array<br />        for(var i = 0; i < all.length; i) {<br />            var element = all[i];<br />            if (isMember(element, classname)) // isMember() is defined below<br />                elements.push(element);       // Add class members to our array<br />        }<br /><br />        // Note that we always return an array, even if it is empty<br />        return elements;<br /><br />        // Determine whether the specified element is a member of the specified<br />        // class.  This function is optimized for the common case in which the<br />        // className property contains only a single classname.  But it also<br />        // handles the case in which it is a list of whitespace-separated classes.<br />        function isMember(element, classname) {<br />            var classes = element.className;  // Get the list of classes<br />            if (!classes) return false;             // No classes defined<br />            if (classes == classname) return true;  // Exact match<br /><br />            // We didn't match exactly, so if there is no whitespace, then<br />            // this element is not a member of the class<br />            var whitespace = /\s/;<br />            if (!whitespace.test(classes)) return false;<br /><br />            // If we get here, the element is a member of more than one class and<br />            // we've got to check them individually.<br />            var c = classes.split(whitespace);  // Split with whitespace delimiter<br />            for(var i = 0; i < c.length; i++) { // Loop through classes<br />                if (c[i] == classname) return true;  // and check for matches<br />            }<br /><br />            return false;  // None of the classes matched<br />        }<br />    }<br />}<br /></pre><pre><br /> </pre><p>The function fuzzyElementSearch accepts five parameters, and is used to find the element based on it’s relation to an an outer element. In other words, we find the element we’re interested in based on the context of the surrounding HTML code.</p><p>So, if we consider the case where we are looking for the element that represents viewset A that we want to hide:</p><pre><td class="th-gr-td" valign="top" rowspan="1" colspan="1"><br /><div id="C11_W43_V44_V48" excevt=""<br />intevt="c:C11_W43_V44_V48:C1_W1_V2_C1_W1_V2_V3_C11_</pre><pre>W43_V44_C11_W43_V44_V48_productdetailviewset.do;" <br />automode="true" tgt="" dhe="true" style="display: inline;"><br /><! Begin C11_W43_V44_V48 ><br /><br /><div id="C1_W1_V2_C1_W1_V2_V3_C11_W43_V44_C11_</pre><pre>W43_V44_V48_productdetailviewset.do" class="th-ajax-area"><br /><! Begin C1_W1_V2_C1_W1_V2_V3_C11_W43_V44_C11_How does fuzzyElementSearch work? It makes use of a function getElements that is from David Flanagan’s book “Javascript” (ISBN 0-596-10199-6, also known as the Rhino book) – this function allows us to search for elements based on class and/or tag name. With the results of this function similar code is used to find all the children of these elements that have the correct tag and regular expression match. I heartily endorse David Flanagan’s book, and if you are interested in learning javascript then consider visiting the book’s web site .

 

1 Comment