4,078 views | View blog reactions

Dynamische, automatische Vervollständigung

Posted on Januar 23rd, 2007 in JSCRIPT by Seidl Michael | 4,078 views

In diesem JScript Blog, wenden wir uns der XMLHTTP Abfrage zu. Die Idee stammt von dieser Seite
Auf der oben genannten Seite wird ein statischer Wert für die automatische Vervollständigung genutzt, ich habe
diese Script so erweitert das mittels XMLHTTP Abfragen, hier dynamische Werte aus den CRM Entitäten abgefragt
werden können.

Hier seht ihr als Beispiel, ein Abfrage nach den aktuell vorhandenen Produkten, die ihr zB. bei zukünftigen Kunden (Leads, Verkaufschancen) hinterlegen könnt, und somit die Möglichkeit habt, zu wissen, welche Produkte dieser bereits verwendet.

JAVASCRIPT [Show Plain Code]:
  1. //Hier weißen wir dem Feld Produkt, eine Aktion zu, die beim klick in das Feld aktiviert wird
  2. crmForm.all.new_produkt.attachEvent("onfocus",Produkt);
  3.  
  4. //Als erstes werden wir mal ein paar Variablen erstellen und deklarieren
  5. //Hier geben wir das Feld an, in dem die automatische Vervollständigung angezeigt werden soll.
  6. var myfeld_produkt="new_produkt";
  7. //Hier wird das Array erstellt, in dem später das Ergebnis der Abfrage kommt.
  8. var myarr_produkt = new Array();
  9. //Hier sind noch ein paar Variablen, die die Interaktion mit den anderen Funktionen ermöglichen.
  10. var my_var=null;
  11. var my_produkt="1";
  12. myarr_produkt=null;
  13. var myob_produkt;
  14. //Nachdem wir alle Variablen haben, hier der Aufruf der Funktion, um die Abfrage zu starten, das Kommando LISTE wird aus dem Grund 2mal ausgeführt, da es einmal beim Onload aktiviert wird, und dann beim klick in das Feld nochmals, das es sonst zu keinem Ergebnis kommt.
  15. liste("product","statuscode","name","1","new_produkt");
  16.  
  17. //Hier nun die Funktion PRODUKT, die beim klick in das Feld Produkt ausgelöst wird.
  18. function Produkt(){
  19. liste("product","statuscode","name","1","new_produkt");
  20. k = function GetListOfCountries()
  21. {
  22.  
  23.     return myarr_produkt;
  24. }
  25. //Nachdem wir die Werte zurückerhalten haben, arbeiten wir damit weiter und übergeben diese an die Funktion SuggestionTextBox, diese, erzeugt uns dann die auswahlliste, im Feld Produkt
  26. my_produkt=my_var;
  27. myarr_produkt= my_produkt.split(‘,’);
  28. myob_produkt= SuggestionTextBox(document.getElementById(myfeld_produkt), k,false);
  29.  
  30. }
  31.  
  32. //Aufruf der Funktion
  33. Produkt();
  34.  
  35.  
  36. //Hier kommen wir nun zur oben angesprochenen Funktion LISTE, beim aufruf oben werden werte mit übergeben die sehr wichtig sind, my_entity=Schemaname der Entität, my_query=Das Feld mit desen Wert ich überprüfen will, my_display=Der Wert den ich zurückbekomme, und der dann im Feld zur Auswahl steht, my_wert=Der Wert, den ich in Kombination mit my_query abfrage, my_felder=Das Feld auf dem die Liste generiert wird. Zusammenfassend, fragen wir hier, ob es in der Entität "Produkt", Werte gibt, desen "statuscode" = 1 ist, also Aktiv, wollen von diesem Ergebnis den Spaltennamen, "Name", also der Produktname, und setzen die ganze Funktion auf das Feld "my_produkt", seht euch den Aufruf etwas weiter oben an, dann sollte alles klar sein.
  37.  
  38. //Nicht vergessen, den Wert "myservername" untern zu ändern
  39. function liste(my_entity,my_query,my_display,my_wert,my_felder)
  40. {
  41.         var templand;
  42.         var serverUrl = "http://myservername/mscrmservices/2006";
  43.         var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  44.         xmlhttp.open("POST", serverUrl + "/crmservice.asmx", false);
  45.         xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8")
  46.         xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple")
  47.         xmlhttp.send("<?xml version=’1.0′ encoding=’utf-8′?>"+"\n\n"+"<soap:Envelope"+
  48.         ‘ xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"’+
  49.         ‘ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"’+
  50.         ‘ xmlns:xsd="http://www.w3.org/2001/XMLSchema">’+
  51.         ‘ <soap:Body>’ +
  52.         ‘ <query xmlns:q1="http://schemas.microsoft.com/crm/2006/Query" xsi:type="q1:QueryExpression" xmlns="http://schemas.microsoft.com/crm/2006/WebServices">’+
  53.                      ‘<q1:EntityName>’+my_entity+‘</q1:EntityName>’+
  54.                      ‘<q1:ColumnSet xsi:type="q1:ColumnSet">’+
  55.                      ‘<q1:Attributes>’+
  56.                      ‘<q1:Attribute>’+my_display+‘</q1:Attribute>’+
  57.                      ‘</q1:Attributes>’+
  58.                      ‘</q1:ColumnSet>’+
  59.                      ‘<q1:Distinct>false</q1:Distinct>’+
  60.                      ‘<q1:Criteria>’+
  61.                      ‘<q1:FilterOperator>And</q1:FilterOperator>’+
  62.                      ‘<q1:Conditions>’+
  63.                      ‘<q1:Condition>’+
  64.                      ‘<q1:AttributeName>’+my_query+‘</q1:AttributeName>’+
  65.                      ‘<q1:Operator>Like</q1:Operator>’+
  66.                      ‘<q1:Values>’+
  67.                      ‘<q1:Value xsi:type="xsd:string">’+my_wert+‘</q1:Value>’+
  68.                      ‘</q1:Values>’+
  69.                      ‘</q1:Condition>’+
  70.                      ‘</q1:Conditions>’+
  71.                      ‘</q1:Criteria>’+
  72.                      ‘<q1:Orders>’+
  73.                      ‘<q1:Order>’+
  74.                      ‘<q1:AttributeName>’+my_query+‘</q1:AttributeName>’+
  75.                      ‘<q1:OrderType>Ascending</q1:OrderType>’+
  76.                      ‘</q1:Order>’+
  77.                      ‘</q1:Orders>’+
  78.                      ‘</query>’+
  79.                      ‘</soap:Body>’+
  80.         ‘ </soap:Envelope>’)
  81.         var result = xmlhttp.responseXML.xml;
  82. //Ab hier haben wir ein fast fertiges Ergebnis, RESULT entspricht jetzt einer XML Datei mit den zurückgegebenen Werten, das ganze müssen wir jetzt noch von allen XML Tags befreien, und in unserer Array packen.
  83. var my_index=result.indexOf(my_display);
  84. if (my_index ==-1)
  85. {
  86. return;
  87. }
  88.         var BEs= result.split("<BusinessEntities>");
  89.  
  90.         var BE = BEs[1].split("<BusinessEntity");
  91.         for (i = 0; i < BE.length; i++)
  92.        
  93.                 {
  94.                
  95.                 first = BE[i].indexOf("<"+my_display+">")+(2+my_display.length);
  96.                 second = BE[i].indexOf("</"+my_display+">");
  97.                 //document.writeln(BE[i].substring(first,second) + ",");
  98.                
  99.                 var tempcount = BE[i].substring(first,second) + ",";
  100.                 if (templand == null)
  101.                         {
  102.                         templand=tempcount;
  103.                         }
  104.                         {
  105.                         templand=templand+tempcount;
  106.                         }
  107.                
  108.                 }
  109. my_var=null;       
  110. my_var=templand;
  111.  
  112. }
  113. //Fertig, wir haben nun die fertigen Werte erhalten und können damit weitergehen.
  114.  
  115.  
  116. //Dies ist nun die Funktion, SuggestionBox, die uns mit den oben erhaltenen Werten unsere Liste generiert.
  117.  
  118. function SuggestionTextBox(textfield, method, preload)
  119. {
  120.            // Hier könnt ihr die maximale Anzahl der Zeilen angeben.
  121.     var maxItems = 6;
  122.     this.suggestionList = new Array();
  123.     this.suggestionListDisplayed = new Array();
  124.     var actual_textfield = textfield;
  125.     var actual_value = ;
  126.     var selectedNumber = 0;
  127.     var countMatches = 0;
  128.     if (preload)
  129.     {
  130.        
  131.         this.suggestionList = method();
  132.     }
  133.     // Die Funktion wird nun unserem Feld zugewiesen
  134.     textfield.attachEvent("onfocus", initTextfield);
  135.    
  136.     function initTextfield()
  137.     {
  138.         // Hier definieren wir, das beim Verlassen des Feldes, alle Werte gelöscht werden   
  139.         textfield.attachEvent("onblur", resetTextfield);
  140.         document.attachEvent("onkeydown", keyDown);
  141.     }
  142.     function resetTextfield(e)
  143.     {
  144.         //Hier löschen wir alle Funktion, die wir mit dem Feld verbunden haben
  145.         document.detachEvent("onkeydown", keyDown);
  146.         textfield.detachEvent("onblur",resetTextfield);
  147.     }
  148.     function keyDown(e)
  149.     {
  150.         keyCode = e.keyCode;
  151.         switch (keyCode)
  152.         {
  153.             case 9: case 13:
  154.                 // enter & tab key
  155.                 if (countMatches > 0)
  156.                 {
  157.                      actual_textfield.value = suggestionListDisplayed[selectedNumber];
  158.                      if (document.getElementById(’suggestion_table’) != null)
  159.                     {
  160.                        document.body.removeChild(document.getElementById(’suggestion_table’));
  161.                     }
  162.                   }
  163.                  break;
  164.             case 38:
  165.                 //Pfeil nach Oben Taste
  166.                 if(selectedNumber > 0 && countMatches > 0)
  167.                 {
  168.                     selectedNumber–;
  169.                     createSuggestionTable();
  170.                 }
  171.                
  172.                 return false;
  173.                 break;
  174.             case 40:
  175.                 //Pfeil nach Unten Taste
  176.                 if(selectedNumber < countMatches-1 && countMatches > 0 && selectedNumber < maxItems)
  177.                 {
  178.                     selectedNumber++;
  179.                        createSuggestionTable();
  180.                 }
  181.                
  182.                 return false;
  183.                 break;               
  184.             default:
  185.                 // Hier gehen wir sicher das die Funktion nicht zu oft aufgerufen wird
  186.                 setTimeout(
  187.                             function()
  188.                             {
  189.                                 executeSuggestion(keyCode)
  190.                             }200 /* in ms */
  191.                            );
  192.                 break;
  193.         }
  194.     }
  195.  
  196.     function executeSuggestion(keyCode)
  197.     {
  198.         selectedNumber = 0;
  199.         countMatches = 0;
  200.        
  201.         actual_value = textfield.value;
  202.        
  203.    
  204.         if (!preload)
  205.         {
  206.  
  207.             this.suggestionList = method();
  208.         }
  209.        
  210.         var re = new RegExp(actual_value, "i");
  211.  
  212.         var re = new RegExp("^" + actual_value, "i");
  213.                
  214.         countMatches = 0;
  215.         this.suggestionListDisplayed = new Array();
  216.  
  217.         for (i = 0; i < this.suggestionList.length; i++)
  218.         {
  219.  
  220.             if (re.test(this.suggestionList[i]) && actual_value != )
  221.             {
  222.                 this.suggestionListDisplayed[countMatches] = this.suggestionList[i];
  223.                 countMatches++;
  224.                
  225.  
  226.                 if (maxItems == countMatches)
  227.                     break;
  228.             }
  229.         }
  230.        
  231.         if (countMatches > 0)
  232.         {
  233.             createSuggestionTable();
  234.         }
  235.         else
  236.         {
  237.             if (document.getElementById(’suggestion_table’))
  238.             {
  239.                 document.body.removeChild(document.getElementById(’suggestion_table’));
  240.             }
  241.         }
  242.     }
  243.    
  244.    
  245.     function createSuggestionTable()
  246.     {
  247.        
  248.         if (document.getElementById(’suggestion_table’))
  249.         {
  250.             document.body.removeChild(document.getElementById(’suggestion_table’));
  251.         }
  252.        
  253.  
  254.         table = document.createElement(‘table’);
  255.         table.id = ’suggestion_table’;
  256.        
  257.         table.width = actual_textfield.style.width;
  258.         table.style.position= ‘absolute’;
  259.         table.style.zIndex = ‘100000′;
  260.  
  261.         table.cellSpacing = ‘1px’;
  262.         table.cellPadding = ‘2px’;
  263.  
  264.  
  265.         topValue = 0;
  266.         objTop = actual_textfield;
  267.         while(objTop)
  268.         {
  269.             topValue += objTop.offsetTop;
  270.             objTop = objTop.offsetParent;
  271.         }
  272.        
  273.         table.style.top = eval(topValue + actual_textfield.offsetHeight) + "px";
  274.  
  275.         leftValue = 0;
  276.         objLeft = actual_textfield
  277.         while(objLeft)
  278.         {
  279.             leftValue += objLeft.offsetLeft;
  280.             objLeft = objLeft.offsetParent;
  281.         }
  282.  
  283.         table.style.left = leftValue + "px";
  284.        
  285.         table.style.backgroundColor = ‘#FFFFFF’;
  286.         table.style.border = "solid 1px #7F9DB9";
  287.         table.style.borderTop = "none";
  288.        
  289.         document.body.appendChild(table);
  290.        
  291.      
  292.         for ( i = 0; i < this.suggestionListDisplayed.length; i++)
  293.         {
  294.                 row = table.insertRow(-1);
  295.                
  296.                 row.id = ’suggestion_row’ + (i);
  297.                 column = row.insertCell(-1);
  298.                 column.id = ’suggestion_column’ + (i);
  299.                
  300.                
  301.                 if (selectedNumber == i)
  302.                 {
  303.                     column.style.color = ‘#ffffff’;
  304.                     column.style.backgroundColor = ‘#316AC5′;
  305.                 }
  306.                 else
  307.                 {
  308.                     column.style.color = ‘#000000′;
  309.                     column.style.backgroundColor = ‘#ffffff’;
  310.                 }
  311.                
  312.                 column.style.fontFamily = ‘Tahoma’;
  313.                 column.style.fontSize = ‘11px’;a
  314.                 column.innerHTML = this.suggestionListDisplayed[i];
  315.                
  316.         }
  317.     }
  318.  
  319.  
  320.     return this;
  321. }

Dies ist nun der ganze Code, um mittels einer XMLHTTP Abfragen gegen den CRM Server, Daten deiner bestimmten Entität zu erhalten, diesen Code einfach in das Onload Event deiner Form kopieren, und sicher gehen, das wie in diesem Beispiel, das Feld “new_produkt” vorhanden ist.
Wie auch oben erwähnt, besteht dieser Code aus einem bereits veröffentlichtem Code Beispiel, das um die dynamische Funktion erweitert wurde, somit gibt es in diesem Code keine klare Linie, was Variablenamen oder Sonstiges anbelangt.

2 Responses to 'Dynamische, automatische Vervollständigung'

Subscribe to comments with RSS or TrackBack to 'Dynamische, automatische Vervollständigung'.

  1. Marcel said,

    on 10. September 2007 at 16:29

    Hallo,

    da ich ein Neuling im Umgang mit Webservices und im MS CRM Umfeld bin hätte ich eine Frage:

    Wenn ich den oben hinterlegten Code im onLoad Event eingebe (myservername hab ich durch meinen Servernamen ersetzt und das Feld new_produkt habe ich hinzugefügt) bekomme ich zwei Fehlermeldungen

    1.
    Zeile: 473
    Zeichen: 72
    Fehler: Objekt erwartet
    Code: 0
    URL: http://“xxxxxx”/tools/fromEditor/preview.aspx

    und 2.

    Zeile: 501
    Zeichen: 33
    Fehler: Ungültiges Zeichen
    Code: 0
    URL: http://“xxxxxx”/tools/fromEditor/preview.aspx

    Wenn du mir sagen könntest was ich falsch mache bzw. vergessen habe wäre ich sehr dankbar.

    mfg Marcel


  2. on 26. November 2007 at 22:30

    Ich werde in kurze den gesamten Code per Download als TXT Fiel anbieten, da es anscheinend Probleme mit der HTML Umsetzung des Codes gibt.