2016-07-15 23 views
0

Ich versuche, die jQuery-Datepicker-Funktion zu verwenden, um Datumsfelder zu füllen, die Teil eines Objektsatzes in einer Hashmap sind.jQuery - Datepicker füllt nicht für hashmap-Datumsfelder

Wir verwenden STRUTS 1, um unsere Formulardaten abzubilden - und für die meisten unserer Daten ist dies ausreichend.

Ich habe diese Felder bereits überprüft und geschrieben, so dass sie durch manuelle Eingabe des Datums ausgefüllt werden können. Jetzt möchte ich den jQuery-Datumsauswahl hinzufügen, damit der Benutzer ein Datum aus einem Popup-Kalender auswählen kann. Ich verwende Chrome. Code-Ausschnitt unten.

<script> 
    $(function() { 
     $(".datePick").datepicker({ 
      dateFormat: 'mm/dd/yy', 
      showOn: "button", 
      buttonImage: "images/calendar.png", 
      buttonImageOnly: true, 
      buttonText: "Select date", 
      onSelect: function(dateText,inst) 
      { 
       id=$(this).attr('id'); 
    pos = id.indexOf("(") + 1; 
    counter = id.slice(pos, -1); 
    id=id.replace("("+counter+")",""); 
       pieces = dateText.split("/"); 
      $("#"+ id+"MM("+counter+")").val(pieces[0]); 
      $("#"+ id+"DD("+counter+")").val(pieces[1]); 
      $("#"+id +"YYYY("+counter+")").val(pieces[2]); 
      } 
     }); 

     }); 

     </script> 

     <!-- "counter" is an integer which keeps track of what iteration of the 
     hashmap is being accessed, propertyValue is a string that allows me to 
     dynamically change the property of each form--> 
     <tr> 
      <td align="right" colspan="1"> 
       <label for="setOfObjectsStartMMDtH("+counter+")"> 
       <%=label.makeLabel(XXXXForm.FORM_KEY_VALUE)%></label> 
      </td> 
      <td align="left" colspan="4"> 
       <% propertyValue="setOfObjectsStartDtHMM("+counter+")";%> 
       <html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>" 
       size="2" maxlength="2"/>&nbsp;/&nbsp; 

       <% propertyValue="setOfObjectsStartDtHDD("+counter+")";%>           
       <html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>" 
       size="2" maxlength="2"/>&nbsp;/&nbsp; 

       <% propertyValue="setOfObjectsStartDtHYYYY("+counter+")";%>          
       <html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>" 
       size="4" maxlength="4"/> 

       <% propertyValue="setOfObjectsStartDtH("+counter+")";%> 
       <html:hidden styleId="<%=propertyValue%>" property="<%=propertyValue%>" 
       styleClass="datePick"+counter></html:hidden> 

Hier sehen meine Getter und Setter aus.

private final HashMap setOfObjects = new HashMap(); 

    /** 
    * @param startDtH the setOfObjectsStartDtH to set 
    */ 
    public void setSetOfObjectsStartDtH(String key, String startDtH) { 
     setOfObjects obj = getSetOfObjects(key); 
     obj.setStartDtH(startDtH); 
    } 

    /** 
    * @return the startDtH 
    */ 
    public String getSetOfObjectsStartDtH(String key) { 
     if(setOfObjectss.containsKey(key)){ 
      SetOfObjects obj = getSetOfObjects(key); 
      return obj.getStartDtH(); 
     } 
     return ""; 
    }  

    /** 
    * @param startDtHDD the startDtHDD to set 
    */ 
    public void setSetOfObjectsStartDtHDD(String key, String startDtHDD) { 
     SetOfObjects obj = getSetOfObjects(key); 
     obj.setStartDtHDD(startDtHDD); 
    } 

    /** 
    * @return the startDtHDD 
    */ 
    public String getSetOfObjectsStartDtHDD(String key) { 
     if(setOfObjectss.containsKey(key)){ 
      SetOfObjects obj = getSetOfObjects(key); 
      return obj.getStartDtHDD(); 
     } 
     return ""; 
    } 

    /** 
    * @param startDtHMM the startDtHMM to set 
    */ 
    public void setSetOfObjectsStartDtHMM(String key, String startDtHMM) { 
     SetOfObjects obj = getSetOfObjects(key); 
     obj.setStartDtHMM(startDtHMM); 
    } 

    /** 
    * @return the startDtHMM 
    */ 
    public String getSetOfObjectsStartDtHMM(String key) { 
     if(setOfObjectss.containsKey(key)){ 
      SetOfObjects obj = getSetOfObjects(key); 
      return obj.getStartDtHMM(); 
     } 
     return ""; 
    } 

    /** 
    * @param startDtHYYYY the startDtHYYYY to set 
    */ 
    public void setSetOfObjectsStartDtHYYYY(String key, String startDtHYYYY) { 
     SetOfObjects obj = getSetOfObjects(key); 
     obj.setStartDtHYYYY(startDtHYYYY); 
    } 

    /** 
    * @return the startDtHYYYY 
    */ 
    public String getSetOfObjectsStartDtHYYYY(String key) { 
     if(setOfObjectss.containsKey(key)){ 
      SetOfObjects obj = getSetOfObjects(key); 
      return obj.getStartDtHYYYY(); 
     } 
     return ""; 
    } 


    private SetOfObjects getSetOfObjects(String key){ 
     if(setOfObjects.containsKey(key))  
      return (SetOfObjects)setOfObjects.get(key); 

     SetOfObjects set = new SetOfObjects(); 
     set.setId(Integer.parseInt(key)); 
     setOfObjects.put(key, set); 
     return set; 
    } 

Und hier ist es, was die SetOfObjects wie folgt aussieht:

public class SetOfObjects{ 

    private String startDtH = ""; 
    private String startDtHMM = ""; 
    private String startDtHDD = ""; 
    private String startDtHYYYY = ""; 

    /** 
    * @param startDtH the startDtH to set 
    */ 
    public void setStartDtH(String startDtH) { 
     startDtH = startDtH; 
    } 

    /** 
    * @return the startDtH 
    */ 
    public String getStartDtH() { 
     return startDtH; 
    } 

    /** 
    * @param startDtHMM the startDtHMM to set 
    */ 
    public void setStartDtHMM(String startDtHMM) { 
     this.startDtHMM = startDtHMM; 
    } 

    /** 
    * @return the startDtHMM 
    */ 
    public String getStartDtHMM() { 
     return startDtHMM; 
    } 

    /** 
    * @param startDtHDD the startDtHDD to set 
    */ 
    public void setStartDtHDD(String startDtHDD) { 
     this.startDtHDD = startDtHDD; 
    } 

    /** 
    * @return the startDtHDD 
    */ 
    public String getStartDtHDD() { 
     return startDtHDD; 
    } 

    /** 
    * @param startDtHYYYY the startDtHYYYY to set 
    */ 
    public void setStartDtHYYYY(String startDtHYYYY) { 
     this.startDtHYYYY = startDtHYYYY; 
    } 

    /** 
    * @return the startDtHYYYY 
    */ 
    public String getStartDtHYYYY() { 
     return startDtHYYYY; 
    } 

} 

Und schließlich ist hier die generierten HTML.

<script> 
    $(function() { 
     $(".datePick").datepicker({ 
      dateFormat: 'mm/dd/yy', 
      showOn: "button", 
      buttonImage: "images/calendar.png", 
      buttonImageOnly: true, 
      buttonText: "Select date", 
      onSelect: function(dateText,inst) 
      { 
       id=$(this).attr('id'); 
    pos = id.indexOf("(") + 1; 
    counter = id.slice(pos, -1); 
    id=id.replace("("+counter+")",""); 
       pieces = dateText.split("/"); 
      $("#"+ id+"MM("+counter+")").val(pieces[0]); 
      $("#"+ id+"DD("+counter+")").val(pieces[1]); 
      $("#"+id +"YYYY("+counter+")").val(pieces[2]); 
      } 
     }); 

     }); 

     </script> 

     <tr> 
      <td align="right" colspan="1"> 
             <label for="setOfObjectsStartMMDtH("+counter+")"><label class="normal">Set of Objects</label></label> 
         </td> 
         <td align="left" colspan="4"> 

       <input type="text" name="setOfObjectsStartDtHMM(0)" maxlength="2" size="2" value="" id="setOfObjectsStartDtHMM(0)">&nbsp;/&nbsp; 


       <input type="text" name="setOfObjectsStartDtHDD(0)" maxlength="2" size="2" value="" id="setOfObjectsStartDtHDD(0)">&nbsp;/&nbsp; 


       <input type="text" name="setOfObjectsStartDtHYYYY(0)" maxlength="4" size="4" value="" id="setOfObjectsStartDtHYYYY(0)"> 


       <input type="hidden" name="setOfObjectsStartDtH(0)" value="" class="datePick" id="setOfObjectsStartDtH(0)"> 

((Anmerkung: Ich bin mir bewusst, dass die ‚‚+ Zähler +‘‘ ist nicht ein entsprechendes Etikett zu schaffen - aber Festsetzung dieser die Kalenderfunktion nicht festgelegt hat))

Der Kalender selbst erscheint mit kein Problem, aber wenn ich ein Datum auswähle, springt die Seite nach oben, und die Datumsfelder sind nicht gefüllt - keine Fehlermeldung erscheint irgendwo auf der Seite, und der Kalender verschwindet auch nicht, wie es normalerweise nach der Auswahl eines Datums wäre .

Was würde dazu führen, dass der Kalender für den jQuery-Datapicker angezeigt wird, aber ich die Kalenderwerte nicht zuweisen kann?

+0

Was hat das mit Java zu tun? – Compass

+0

@Compass Beachten Sie die Java-Snippets - obwohl es nicht besonders wichtig ist. Ich werde dieses Tag entfernen. – Zibbobz

+0

In der Konsole für den Entwickler-Modus/Tools erhalten Sie einen Fehler? – dama

Antwort

1

Ich denke, das Problem ist Verkettung der ID-Selektoren. Sie müssen den Klammern entkommen.

starten:

 $("#"+ id+"MM\\("+counter+"\\)").val(pieces[0]); 
     $("#"+ id+"DD\\("+counter+"\\)").val(pieces[1]); 
     $("#"+id +"YYYY\\("+counter+"\\)").val(pieces[2]); 
+0

Ich werde ehrlich sein - ich dachte nicht, das würde funktionieren, aber es hat funktioniert! Vielen Dank! – Zibbobz

1

Zunächst einmal haben Sie eine Mischung aus zwei Konzepten Backend Code (Java) und ein clientseitige Code (JavaScript). Im Allgemeinen, in einer Web-Anwendung, wenn ein Benutzer eine Anfrage stellt, die Ihren Server trifft, der den Backend-Code ausführt, um eine Antwort zu generieren und zurückzusenden - diese Antwort hat die Form von HTML/JS/CSS, die zur Anzeige von Dingen verwendet wird im Browser. Im Browser kann der JavaScript-Code ausgeführt werden, um weitere Funktionen bereitzustellen.

Dies ist die Grundidee gegen die meisten Web-Anwendungen - Java kann mit PHP oder C# oder JavaScript (in Form von NodeJS) oder vielen anderen als Backend ersetzt werden, aber Sie haben beide zu unterschiedlichen Zeiten Umgebungen ausgeführt und sogar Maschinen sowie geografische Standorte.

Mit diesem gesagt können beide kommunizieren. Nicht in direkter Weise, zum Beispiel, können Sie nicht MyServerObject.setMyValue() von der Client-Seite aufrufen, aber wenn Sie von Frontend-Backend übertragen möchten, gibt es grundsätzlich zwei Möglichkeiten, es zu tun:

  • Form Unterwerfung - das ist heutzutage die "Old-School" -Methode. Nicht, dass es schlecht ist, aber nicht wie verwendet.Im Wesentlichen haben Sie eine <form> auf der Seite mit einer Reihe von <input> s, die manipuliert werden kann und wenn das Formular übermittelt wird, überträgt es alle Werte an das Backend. Dies hängt davon ab, wie Sie die Daten erhalten möchten, aber es läuft auf the action attribute auf dem Formular. Dies führt dazu, dass die Seite als Teil der Übermittlung neu geladen wird und der Benutzer an anderer Stelle umgeleitet wird (obwohl möglicherweise auf dieselbe Seite). Es wird als aufdringlich und nicht als benutzerfreundlich angesehen, daher die "Old-School" -Eigenschaft. Auf der anderen Seite wird es nativ von HTML unterstützt und jeder Browser weiß, wie man mit Formularen umgeht.
  • AJAX-Anfragen - obwohl nicht in irgendeiner Weise "neu", dies ist in der Regel die bevorzugte Art und Weise Client-Side-Code kommuniziert mit dem Back-End. Es beinhaltet das Senden einiger Daten an den Server, ohne die Seite verlassen zu müssen und ohne dass der Benutzer davon Kenntnis hat. Es bietet somit eine bessere Benutzererfahrung und es ist auch einfacher, mit dem Backend umzugehen, da Sie gestalten können, wie Ihre Daten besser ankommen (Formulare geben Ihnen nur Schlüssel/Wert-Paare).

Zwar gibt es viele Möglichkeiten gibt, AJAX zu erreichen, die jQuery .ajax() und seine beiden Kürzeln .get() und .post() sind sehr bequem und einfach. Was Sie wahrscheinlich tun werden, ist in Ihrem onSelect Handler Anruf so etwas wie: $.post("some/path/on/my/server", myData) wo das myData Objekt wird eine der Daten, die Sie wollen, die als JSON gesendet werden und some/path/on/my/server ist ein Teil des Servers, der diese Daten akzeptieren kann. Im Allgemeinen würde dieser Pfad am Ende nur serverseitigen Code aufrufen, der die Daten weiterleitet - in alten Tagen war es wahrscheinlich, dass Sie einfach ein in Perl geschriebenes CGI-Skript trafen, aber heutzutage wird nur Ihr Backend über einen URI angezeigt. Wie genau dieser Pfad implementiert wird, kann variieren, und ich bin leider nicht vertraut mit Struts, wie es dort gemacht werden würde, aber ich kann mir vorstellen, dass es nicht schwer sein muss.

Sobald Ihr Backend die Daten empfängt, ist es üblich, es in irgendeiner Weise zu verarbeiten (überprüfen Sie die Gültigkeit, bereinigen Sie, entscheiden Sie, was zu tun ist) und übergeben Sie es dann zur weiteren Verarbeitung in anderen Teilen die Anwendung. In Ihrem Fall werden Sie wahrscheinlich einige Daten erhalten, dann einige Objekte mit Daten erstellen und befüllen, dann ... tun, was auch immer benötigt wird. Wenn Sie jedoch wissen müssen, der Benutzer eine Anfrage ausgegeben hat, und dieser Benutzer mit ihren Kalendern Sachen macht, müssen Sie möglicherweise weitere Informationen hinzufügen. Viele serverseitige Sprachen haben das Konzept von Sitzungen, das nur ein Kontext für einen bestimmten Benutzer ist. Wenn jemand einen Kalender ändert, können Sie herausfinden, wer auf der Sitzung basiert und den entsprechenden Kalender finden. Sitzungen werden wahrscheinlich für Sie eingerichtet und Sie müssen möglicherweise nichts tun, um sie zu verwenden. Eine Alternative zur Verwendung von Sitzungen ist jedoch die Weitergabe von Tokens für den Benutzer - dies geschieht in Form einer Art von Information - Benutzername, Schlüssel, Sitzungs-ID, die als Teil der AJAX-Anfrage übertragen werden kann und identifiziert, wer sie ausgegeben hat.

In jedem Fall, wenn Sie Informationen an den Client zurückgeben müssen, zum Beispiel "Aktion erfolgreich" oder "fehlgeschlagen", kann das Backend auf mehr oder weniger zwei Arten auf die AJAX-Anfrage antworten. Eine Möglichkeit besteht darin, einfach einige Daten vom einfachsten boolean zurückzusenden, um Erfolg/Misserfolg beim Zurückgeben von Strings oder ganzen Objekten (wahrscheinlich serialisiert und in JSON übertragen) anzuzeigen, um die Antwort anzuzeigen. Die zweite Möglichkeit besteht darin, eine response code zu senden, um anzuzeigen, was passiert ist. In Wirklichkeit werden Sie wahrscheinlich eine Mischung aus beidem verwenden. Auf der Clientseite, würde dies mit der jQuery-Handler mithilfe von

$.post("some/path/on/my/server", myData) 
.done(function() { alert("sending data succeeded") }) 
.fail(function() { alert("sending data failed") }) 
.always(function() { alert("finished sending data") }) 

behandelt werden Dies wird mit der jQuery promises eine Alternative ist unter Angabe der Erfolg/Misserfolg Handler als Teil des $.ajax Anruf. Es muss darauf hingewiesen werden, dass die alert nur zur Veranschaulichung dient - Sie werden wahrscheinlich die Benutzer auf eine andere Weise benachrichtigen. Oder vielleicht gar nicht, da es möglicherweise nicht relevant ist, solange es funktioniert, also könnten Sie sie nur benachrichtigen, wenn es scheitert.

+0

Wish Ich könnte dieser Antwort mehr Anerkennung für die Mühe und den Nutzen geben, die es bringt - aber Damas Antwort hat das Problem sofort behoben, ohne irgendwelche Informationen zwischen dem vorderen und hinteren Ende weitergeben zu müssen. – Zibbobz

+0

Ich werde dir das Kopfgeld geben, weil du viel Hilfe geleistet hast. :) – Zibbobz