Materialien Abo-Modul

Hier finden Sie ausführlichere Code-Beispiele für das Abo-Modul.

Wegweiser: Abo-Modul

Diese Umsetzung vermeidet Weiterleitungen auf ws_bank_manage.htm und ws_address_manage.htm. Der Nutzer bleibt auf der Seite ws_product.htm oder ws_subscription_manage.htm.
Die Modal-Fenster wurden mit Bootstrap 4 realisiert. Die Funktionen sind auch mit anderen Bootstrap Versionen kompatibel.

Zusätzlich werden abhängige Varianten berücksichtigt.

1. Template der Produktdetailansicht (ws_product.htm) anpassen

...
{PR-SubscriptionProduct}

   <!-- Wird benötigt, wenn das Abo-Produkt abhängige Varianten besitzt -->
   ~PR-PrintHiddenDepVariations~
   <!-- Anzeige der Produktvarianten, z. B. aus der incl_fast_includes.htm -->
   ~WS-Fast_Include(Incl-Variants)~

   Bitte wählen Sie Ihre Lieferung:<br>

   Einmalige Lieferung<br>
   {!PR-DepVarQuantity}
      <label for="~PR-Quantity_Input~" class="control-label">Menge</label><br>
      <input type="text" name="~PR-Quantity_Input~" value="~PR-Quantity~" autocomplete="false" class="form-control">
   {/!PR-DepVarQuantity}

   {PR-DepVarQuantity}
      <input type="hidden" name="~PR-Quantity_Input~" value="1" autocomplete="false">
   {/PR-DepVarQuantity}

   {ST-DepVar_OK}
      <button type="submit" name="~BT-ProductAddToBasket_Ajax~" data-ws-ajax="basket">Warenkorb</button><br>
   {/ST-DepVar_OK}

   {!ST-LoggedIn}
      Sie benötigen ein Kundenkonto, um ein Abonnement bei uns abschließen zu können.<br>
      <span onclick="$('#modal-loginFields').modal();">Melden Sie sich jetzt an</span><br>
   {/!ST-LoggedIn}

   {ST-LoggedIn}
      {SUBS-CycleSelection}
         Lieferintervall<br>
         <select name="~SUBS-CycleSelection_input~" onchange="SubmitSelection(); return false;">
            {@SUBS-CycleSelection_data}
               <option value="~SUBS-CycleSelection_data_value~" ~SUBS-CycleSelection_data_selected~>~SUBS-CycleSelection_data_descr~</option>
            {/@SUBS-CycleSelection_data}
         </select><br>
      {/SUBS-CycleSelection}

      {!A-FirstName}
         <span data-toggle="modal" data-target="#modal-addressFields">Rechnungsadresse erstellen</span><br>
      {/!A-FirstName}

      {A-FirstName}
         <div id="subscriptionAddress"></div><br>
         <span data-toggle="modal" data-target="#modal-addressFields">Adresse bearbeiten</span><br>
         <div id="subscriptionBank"></div><br>
         <span data-toggle="modal" data-target="#modal-bankFields">Bankverbindung bearbeiten</span>
      {/A-FirstName}
   {/ST-LoggedIn}

   {!A-FirstName}~DC-FPAboOrderOk_set(false)~{/!A-FirstName}
   {!SUBS-BankData}~DC-FPAboOrderOk_set(false)~{/!SUBS-BankData}
   {!SUBS-CycleSelection}~DC-FPAboOrderOk_set(false)~{/!SUBS-CycleSelection}

   <input {DC-FPAboOrderOk(false)}disabled{/DC-FPAboOrderOk(false)} name="~BT-Subscription~" value="Abo aktivieren und zahlungspflichtig bestellen" type="submit">

   <!-- Modal Fenster steht außerhalb des Produktforms stehen -->
   <div class="modal fade" id="modal-loginFields" tabindex="-1" role="dialog">
      <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content" id="modal-content-loginFields">
            <div class="modal-body">
               <div class="row">
                  <div class="col-12">
                     <h1 style="float: left;">Melden Sie sich an</h1>
                     <button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="wsManualModalCloseLogin();"><span aria-hidden="true">×</span></button>
                  </div>
               </div>
               <div id="modal-body-loginFieldsError" class="row"></div>
               <div id="modal-body-loginFields" class="row"></div>
            </div>
         </div>
      </div>
   </div>

   <div class="modal fade" id="modal-addressFields" tabindex="-1" role="dialog">
      <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content" id="modal-content-addressFields">
            <div class="modal-body">
               Adresse bearbeiten
               <button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="wsManualModalClose();"><span aria-hidden="true">×</span></button>
               <div id="modal-body-addressFields"></div>
            </div>
        </div>
      </div>
   </div>
   <div class="modal fade" id="modal-bankFields" tabindex="-1" role="dialog">
      <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content" id="modal-content-bankFields">
            <div class="modal-body">
               Bankdetails bearbeiten
               <button type="button" data-dismiss="modal" aria-label="Close" onclick="wsManualModalCloseBank();"><span aria-hidden="true">×</span></button>
               <div id="modal-body-bankFields">
                  <div id="bankManageIframe">
                     <iframe src="~WS-EnsureNextLinkContainsURLParams~~WS-BankManageLink~&otp3=updateBankSubscription" frameborder="0" allowfullscreen class="iframe" style="height:605px;width:100%"></iframe>
                  </div>
                  <a onclick="wsManualModalCloseBank();">Fertig</a>
               </div>
            </div>
         </div>
      </div>
   </div>

   {ST-LoggedIn}
     <script>
       $(document).on("click","#modal-addressFields",function(e){
         if(!$(event.target).is("#modal-addressFields *")) {
           wsManualModalClose();
         }
       })

       $(document).on("click","#modal-bankFields",function(e){
         if(!$(event.target).is("#modal-bankFields *")) {
           wsManualModalClose();
         }
       })

       function wsManualModalClose(){
         $("#modal-addressFields").modal("hide");
       }

       function wsManualModalCloseBank(){
         $("#modal-bankFields").modal("hide");
         ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-BankManageLink~&otp3=updateBankSubscription', '~WS-Charset~', wsAjaxLoadBankStart, wsAjaxLoadBankError, 'wsAjaxLoadBankResponseSuccess()', 'wsAjaxLoadBankResponseError()');
       }

       function wsAjaxLoadAdrressStart(){}
       function wsAjaxLoadAdrressError(){}
       function wsAjaxLoadAdrressResponseSuccess(){}
       function wsAjaxLoadAdrressResponseError(){}
       function wsAjaxLoadAdrressSaveResponseSuccess(){}
       ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-AddrManageLink~&otp3=updateAddressSubscription', '~WS-Charset~', wsAjaxLoadAdrressStart, wsAjaxLoadAdrressError, 'wsAjaxLoadAdrressResponseSuccess()', 'wsAjaxLoadAdrressResponseError()');

       function wsAjaxLoadBankStart(){}
       function wsAjaxLoadBankError(){}
       function wsAjaxLoadBankResponseSuccess(){}
       function wsAjaxLoadBankResponseError(){}
       ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-BankManageLink~&otp3=updateBankSubscription', '~WS-Charset~', wsAjaxLoadBankStart, wsAjaxLoadBankError, 'wsAjaxLoadBankResponseSuccess()', 'wsAjaxLoadBankResponseError()');
     </script>
   {/ST-LoggedIn}

   {!ST-LoggedIn}
      {DC-SPRegisterParamsOTP1}
         ~DC-FPRegisterParamsOTP1_set(otp1=$DC-SPRegisterParamsOTP1$)~
      {/DC-SPRegisterParamsOTP1}

      {DC-SPRegisterParamsOTP3}
         ~DC-FPRegisterParamsOTP3_set(otp3=$DC-SPRegisterParamsOTP3$)~
      {/DC-SPRegisterParamsOTP3}

      {!DC-CompareStringInList($DC-SPRegisterParamsOTP3$,loginSubscription)}
         ~DC-FPRegisterParamsOTP3_set(otp3=loginSubscription)~
      {/!DC-CompareStringInList($DC-SPRegisterParamsOTP3$,loginSubscription)}

      {DC-SPRegisterParamsOTPLoginType}
         ~DC-FPRegisterParamsOTPLoginType_set(otplogintype=$DC-SPRegisterParamsOTPLoginType$)~
      {/DC-SPRegisterParamsOTPLoginType}

      <script>
        function wsAjaxLoginStart(){}
        function wsAjaxLoginError(){}
        function wsAjaxLoginResponseSuccess(){}
        function wsAjaxLoginResponseError(){}

        function ws_AJAXSendLoginForSubProductStart(){};
        function ws_AJAXSendLoginForSubProductError(){};
        function ws_AJAXSendLoginForSubProductResponseSuccess(){
          ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~PR-DepVarLink~', '~WS-Charset~', ws_AJAXPRStart, ws_AJAXPRError, 'ws_AJAXPRSubProductResponseSuccess()', 'ws_AJAXPRResponseError()');
        };
        function ws_AJAXSendLoginForSubProductResponseError(){};

        function ws_AJAXSendRegisterForSubProductStart(){};
        function ws_AJAXSendRegisterForSubProductError(){};
        function ws_AJAXSendRegisterForSubProductResponseSuccess(){
          ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~PR-DepVarLink~&otp3=loginSubscription&type=loginUser&otplogintype=newuser&otp1=NewUserSubscription', '~WS-Charset~', ws_AJAXPRStart, ws_AJAXPRError, 'ws_AJAXPRSubProductResponseSuccess()', 'ws_AJAXPRResponseError()');
        };
        function ws_AJAXSendRegisterForSubProductResponseError(){};

        function ws_AJAXPRSubProductResponseSuccess(){}

        ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-LoginLink~{DC-FPRegisterParamsOTP1}&~DC-FPRegisterParamsOTP1~{/DC-FPRegisterParamsOTP1}{DC-FPRegisterParamsOTP3}&~DC-FPRegisterParamsOTP3~{/DC-FPRegisterParamsOTP3}{DC-FPRegisterParamsOTPLoginType}&~DC-FPRegisterParamsOTPLoginType~{/DC-FPRegisterParamsOTPLoginType}', '~WS-Charset~', wsAjaxLoginStart, wsAjaxLoginError, 'wsAjaxLoginResponseSuccess()', 'wsAjaxLoginResponseError()');
      </script>
   {/!ST-LoggedIn}

   {ST-LoggedIn}
     <script>
       function ws_AJAXPRSubProductResponseSuccess(){
         $("#modal-loginFields").modal("hide");
       }
     </script>
   {/ST-LoggedIn}

   <script>
     function ws_AJAXregisterNewUserStart(){}    
     function ws_AJAXregisterNewUserResponseSuccess(){}
     function ws_AJAXregisterNewUserResponseError(){}
     function ws_AJAXregisterNewUserError(){}
     function wsManualModalCloseLogin(){
       $("#modal-loginFields").modal("hide");
     }
     // Formulare per Ajax nachladen
     function ws_AJAXsendFormTemplateStart() {}
     function ws_AJAXsendFormTemplateResponseSuccess() {}
     function ws_AJAXsendFormTemplateResponseError() {}
     function ws_AJAXsendFormTemplateError() {}
   </script>

{/PR-SubscriptionProduct}
...

2. Template der Anmeldeseite (ws_login.htm) anpassen

...
{!WS-OTP3(loginSubscription)}
   ...
   <!-- Inhalt, der auf ws_login.htm angezeigt wird und nicht für das Modal-Fenster oder Abo-Modul verwendet wird. -->
   ...
{/!WS-OTP3(loginSubscription)}

{WS-OTP3(loginSubscription)}
{ST-Ajax}
   <WS-Ajax-modal-body-loginFields>
   {!WS-OTP1(NewUserSubscription)}
      <form action="~FORM-QuickLogin~" method="post" id="quicklogin_subProduct_input">
         <input type="hidden" name="otp1" value="KnownUserSubscription">
         <input type="hidden" name="otp3" value="loginSubscription">
         <input type="hidden" name="otplogintype" value="newuser">
         ~DC-FPQuickloginID_set(quicklogin_subProduct_input)~

         <div class="{WS-Email_error}has-error has-feedback{/WS-Email_error}">
            <div class="inputLabelFocus" data-placeholder="E-Mail-Adresse *">
               <label for="~WS-Email_input~" class="control-label">E-Mail-Adresse *</label>
               <input type="email" name="~WS-Email_input~" value="~WS-Email~" maxlength="80" class="input~WS-Email_error~ form-control">
               {WS-Email_error}<span class="form-control-feedback" aria-hidden="true"></span>{/WS-Email_error}
            </div>
         </div>
         <div class="has-feedback {WS-PW_error}has-error{/WS-PW_error}">
            <div class="inputLabelFocus" data-placeholder="Passwort *">
               <label for="~WS-PW_input~" class="control-label">Passwort *</label>
               <input type="password" maxlength="128" name="~WS-PW_input~" value="~WS-PW~" class="input~WS-PW_error~ form-control">
            </div>
         </div>
         <button type="submit" onclick="return ws_AJAXsendFormTemplate('~DC-FPQuickloginID~', '~WS-CharSet~', ws_AJAXSendRegisterForSubProductStart, ws_AJAXSendRegisterForSubProductError, 'ws_AJAXSendRegisterForSubProductResponseSuccess()', 'ws_AJAXSendRegisterForSubProductResponseError()');">Anmelden</button>
         <span onclick="ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-LoginLink~&otp3=loginSubscription&type=loginUser&otplogintype=newuser&otp1=NewUserSubscription&act=subscription&otpsubscriptionprodindex=~PR-ProdIndex~{PR-DepVariations}&otpsubscriptionvarindex=~PR-VarIndex~{/PR-DepVariations}', '~WS-Charset~', wsAjaxLoginStart, wsAjaxLoginError, 'wsAjaxLoginResponseSuccess()', 'wsAjaxLoginResponseError()');">Kundenkonto erstellen</span>
      </form>
      ~DC-SPRegisterParamsOTP1_set($WS-OTP1$)~
      ~DC-SPRegisterParamsOTP3_set($WS-OTP3$)~
      ~DC-SPRegisterParamsOTPLoginType_set($WS-OTPlogintype$)~
   {/!WS-OTP1(NewUserSubscription)}

   {WS-OTP1(NewUserSubscription)}
      <form action="~FORM-LoginNewUser~" id="ws_newuser_content_subscription" method="Post" autocomplete="nono" data-ws-ajax="NewUserLoginSubscription">
         ~DC-FPQuickloginID_set(ws_newuser_content_subscription)~
         <input type="hidden" name="otp1" value="NewUserSubscription">
         <input type="hidden" name="otp3" value="loginSubscription">
         <input type="hidden" name="otplogintype" value="newuser">

         <div class="{WS-NewEmail_error} is-invalid{/WS-NewEmail_error}">
            <div class="inputLabelFocus" data-placeholder="E-Mail Adresse">
               <label for="~WS-NewEmail_input~" class="control-label">E-Mail Adresse *</label>
               <input type="email" name="~WS-NewEmail_input~" value="~WS-NewEmail~" maxlength="128" class="form-control{WS-NewEmail_error} is-invalid{/WS-NewEmail_error}">
            </div>
         </div>

         <div class="{WS-NewPW_error} is-invalid{/WS-NewPW_error}">
            <div class="inputLabelFocus" data-placeholder="Passwort">
               <label for="~WS-NewPW_input~" class="control-label">Passwort *</label>
               <input type="password"  maxlength="128" name="~WS-NewPW_input~" value="~WS-NewPW~" class="form-control{WS-NewPW_error} is-invalid{/WS-NewPW_error}" data-container="body" data-toggle="popover" data-placement="top" data-trigger="focus" data-content="Ihr Passwort sollte mindestens 8 Zeichen lang sein und aus einer Buchstaben-Zahlen-Kombination bestehen.">
            </div>
            ~WS-Fast_Include(Incl-WSLoginPasswordChecker)~
         </div>

         <div class="{WS-PWAgain_error} is-invalid{/WS-PWAgain_error}">
            <div class="inputLabelFocus" data-placeholder="Passwort wiederholen *">
               <label for="~WS-PWAgain_input~" class="control-label">Passwort wiederholen *</label>
               <div class="input-group">
                  <input type="password" maxlength="128" name="~WS-PWAgain_input~" value="~WS-PWAgain~" class="form-control{WS-PWAgain_error} is-invalid{/WS-PWAgain_error}" data-container="body" data-toggle="popover" data-placement="top" data-trigger="focus" data-content="Ihr Passwort sollte mindestens 8 Zeichen lang sein und aus einer Buchstaben-Zahlen-Kombination bestehen.">
                  <button type="submit" onclick="return ws_AJAXsendFormTemplate('~DC-FPQuickloginID~', '~WS-CharSet~', ws_AJAXSendRegisterForSubProductStart, ws_AJAXSendRegisterForSubProductError, 'ws_AJAXSendRegisterForSubProductResponseSuccess()', 'ws_AJAXSendRegisterForSubProductResponseError()');"><b>Submit</b></button>
               </div>
            </div>
         </div>
      </form>

      <span onclick="ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-LoginLink~&otp3=loginSubscription&type=loginUser&otplogintype=newuser&act=subscription&otpsubscriptionprodindex=~PR-ProdIndex~{PR-DepVariations}&otpsubscriptionvarindex=~PR-VarIndex~{/PR-DepVariations}', '~WS-Charset~', wsAjaxLoginStart, wsAjaxLoginError, 'wsAjaxLoginResponseSuccess()', 'wsAjaxLoginResponseError()');">Ich habe bereits ein Kundenkonto</span>
      ~DC-SPRegisterParamsOTP1_set($WS-OTP1$)~
      ~DC-SPRegisterParamsOTP3_set($WS-OTP3$)~
      ~DC-SPRegisterParamsOTPLoginType_set($WS-OTPlogintype$)~
   {/WS-OTP1(NewUserSubscription)}
   </WS-Ajax-modal-body-loginFields>
{/ST-Ajax}
{/WS-OTP3(loginSubscription)}
...

3. Template für die Verwaltung der Rechnungsadresse im Kundenkonto (ws_address_manage.htm) anpassen

...
{ST-Ajax}
   <!-- Adressfelder. Werden auf ws_product.htm angezeigt -->
   <WS-Ajax-subscriptionAddress>
      {A-Salutation}~A-Salutation~ ~A-FirstName~{A-LastName} ~A-LastName~{/A-LastName}{/A-Salutation}
      {A-Street1}~A-Street1~{/A-Street1}
      {A-Zip}~A-Zip~{/A-Zip}{A-City} ~A-City~{/A-City}
   </WS-Ajax-subscriptionAddress>
{/ST-Ajax}
...
{A-Edit}

   <!-- negativ geklammert, damit das Formular nicht im Modal-Fenster gezeigt wird -->
   {!WS-OTP3(updateAddressSubscription)}
      <div id="addressformwrapper">
         {ST-Ajax}<WS-Ajax-addressformwrapper>{/ST-Ajax}
            <form action="~FORM-AddrManage~" method="post" autocomplete="" id="addressform">
               ...
            </form>
         {ST-Ajax}</WS-Ajax-addressformwrapper>{/ST-Ajax}
      </div>
   {/!WS-OTP3(updateAddressSubscription)}

   <!-- Formular im Modal-Fenster -->
   {WS-OTP3(updateAddressSubscription)}
      {ST-Ajax}<WS-Ajax-modal-body-addressFields>{/ST-Ajax}
         <form action="~FORM-AddrManage~" method="post" autocomplete="" id="addressform">
            <input type="hidden" name="otp3" value="updateAddressSubscription">
            ~WS-Fast_Include(Incl-InvoiceAddressMsg)~
            Felder, die mit einem "*" gekennzeichnet sind, sind erforderlich.
            ~WS-Fast_Include(Incl-InvoiceAddressFields)~
            <button type="submit" name="~BT-Addr_Save~" onclick="return (ws_AJAXsendFormTemplate('addressform', '~WS-CharSet~', ws_AJAXsendFormTemplateStart, ws_AJAXsendFormTemplateError, 'ws_AJAXsendFormTemplateResponseSuccess()', 'ws_AJAXsendFormTemplateResponseError()'));">Speichern</button>
         </form>
      {ST-Ajax}</WS-Ajax-modal-body-addressFields>{/ST-Ajax}
   {/WS-OTP3(updateAddressSubscription)}

{/A-Edit}
...

 

4. Template für die Verwaltung der Bankdaten (ws_bank_manage.htm) anpassen

...
<main>
   {ST-Ajax}
      <WS-Ajax-subscriptionBank>
         {SUBS-BankData}
            {Bank-UserDescr}<span>~Bank-UserDescr~</span><br>{/Bank-UserDescr}
            {BANK-Owner}<span>~BANK-Owner~</span><br>{/BANK-Owner}
            {BANK-IBAN}<span>~BANK-IBAN~</span><br>{/BANK-IBAN}
            {BANK-BIC}<span>~BANK-BIC~</span><br>{/BANK-BIC}
            {BANK-Bank}<span>~BANK-Bank~</span>{/BANK-Bank}
            {SUBS-BankIndex_input}<input type="hidden" name="~SUBS-BankIndex_input~" value="">{/SUBS-BankIndex_input}
         {/SUBS-BankData}
         {!SUBS-BankData}
            Um Ihr Abonnement abzuschließen, wählen Sie bitte eine Bankverbindung aus, über die Ihr Abonnement zukünftig bezahlt werden soll.
            <span data-toggle="modal" data-target="#modal-bankFields">Bankverbindung auswählen</span>
         {/!SUBS-BankData}
      </WS-Ajax-subscriptionBank>
   {/ST-Ajax}
   
   
   {!WS-OTP3(updateBankSubscription)}
      <!-- Alle Inhalte, die nicht im Modal-Fenster gezeigt werden sollen -->
   {/!WS-OTP3(updateBankSubscription)}


   <!-- Inhalt wird im Modal-Fenster angezeigt -->
   {WS-OTP3(updateBankSubscription)}
      <!-- Modal Content für Abo-Modul -->
      <div id="bankManageContentIframe">
         {ST-Ajax}<WS-Ajax-bankManageContentIframe>{/ST-Ajax}

            {SUBS-FixedPaymentCodeUsed(4)}
               {SUBS-Bankdata}
                  Ihre Abonnements werden mit folgender Bankverbindung bezahlt:
                  ~WS-Fast_Include(Incl-Banks)~
                  <span href="~BANK-EditLink~&otp3=updateBankSubscription">bearbeiten</span>
               {/SUBS-Bankdata}

               ~SUBS-BankSelection~
               {BANK-BankSelection}
                  {SUBS-Bankdata}
                     Andere Bankverbindung wählen
                  {/SUBS-Bankdata}

                  {!SUBS-BankData}
                     Sie haben noch keine Bankverbindung ausgewählt. Bitte wählen Sie eine Bankverbindung aus, damit sie Abonnements abschließen können.
                  {/!SUBS-Bankdata}

                  <form action="~FORM-Subscription~" id="subscriptionBank" method="POST">
                     <select class="form-control" onchange="return ws_AJAXsendForm('subscriptionBank','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(), 'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()')" name="~SUBS-BankIndex_input~">
                        <option value="empty">Bitte wählen</option>
                        {@BANK-Data}<option value="~BANK-BankSelection_code~" {DC-CompareDigitIBE($BANK-BankSelection_code$,$SUBS-BankIndex$,$BANK-BankSelection_code$)}selected{/DC-CompareDigitIBE($BANK-BankSelection_code$,$SUBS-BankIndex$,$BANK-BankSelection_code$)}>{BANK-UserDescr}~BANK-UserDescr~{/BANK-UserDescr} (~BANK-IBAN~, ~BANK-Bank~)</option>{/@BANK-Data}
                     </select>
                  </form>
               {/BANK-BankSelection}

               {!BANK-BankSelection}
                  Sie haben in Ihrem Kundenkonto noch keine Bankverbindungen hinterlegt. Bitte hinterlegen Sie mindestens eine Bankverbindung, um ein Abonnement abzuschließen
               {/!BANK-BankSelection}

               {Bank-NewBankLink}
                  <a href="~Bank-NewBankLink~&otp3=updateBankSubscription">Neue Bankverbindung anlegen</a>
               {/Bank-NewBankLink}

            {/SUBS-FixedPaymentCodeUsed(4)}

            {BANK-Edit}
               Bankverbindung bearbeiten
               <form action="~FORM-BankManage~" method="POST" autocomplete="%%GlobalInputAutocompleteTxt%%" id="ws_bank_form">
                  <input type="hidden" name="otp3" value="updateBankSubscription">

                  {MSG-Bank_Notify}
                     {BANK-SavedIndex}
                        ~MSG-Bank_Notify~
                     {/BANK-SavedIndex}
                  {/MSG-Bank_Notify}

                  {BANK-SEPADirectMandateType(2)}
                     Für diese Bankverbindung liegt ein wiederkehrendes Mandat vor.<br>Die Daten dieser Bankverbindung sind daher nicht änderbar.<br>Legen Sie bitte bei Bedarf einfach eine neue Bankverbindung an.
                  {/BANK-SEPADirectMandateType(2)}

                  {!BANK-SEPADirectMandateType(2)}
                     Bitte geben Sie in untenstehende Felder Ihre Bankdaten ein. <br>Felder, die mit einem "*" gekennzeichnet sind, sind erforderlich.
                  {/!BANK-SEPADirectMandateType(2)}

                  ~WS-Fast_Include(Incl-BankFieldsInputSEPA)~
                  <div class="inputLabelFocus{BANK-UserDescr_error} is-invalid{/BANK-UserDescr_error}" data-placeholder="~BANK-UserDescr_text~">
                     <label for="~BANK-UserDescr_input~" class="control-label">~BANK-UserDescr_text~</label>
                     <input type="text" name="~BANK-UserDescr_input~" maxlength="80" value="~BANK-UserDescr~" class="form-control">
                     {BANK-UserDescr_error}<span class="invalid-feedback">~BANK-UserDescr_errortext~</span>{/BANK-UserDescr_error}
                  </div>

                  {BANK-Mode_Manage}
                     {!BANK-SEPADirectMandateType(2)}
                        {BT-BankSubmit}
                           <button type="submit" name="~BT-BankSubmit~">speichern</button>
                        {/BT-BankSubmit}
                     {/!BANK-SEPADirectMandateType(2)}
                  {/BANK-Mode_Manage}
               </form>
            {/BANK-Edit}
         {ST-Ajax}</WS-Ajax-bankManageContentIframe>{/ST-Ajax}
      </div>

      <script src="/$WS/ws_sysdata/js/ws-module-ajaxgeneric-1.8.5.js"></script>
      <script>
         function ws_AJAXSubscriptionResponseSuccess(){
            ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-BankManageLink~&otp3=updateBankSubscription', '~WS-Charset~', wsAjaxLoadBankStart, wsAjaxLoadBankError, 'wsAjaxLoadBankResponseSuccess()', 'wsAjaxLoadBankResponseError()');
         }
         function ws_AJAXSubscriptionStart(){}
         function ws_AJAXSubscriptionError(){}
         function ws_AJAXSubscriptionResponseError(){}
         function ws_AJAXSubscriptionEditBankResponseSuccess(){
            ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-BankManageLink~&otp3=updateBankSubscription', '~WS-Charset~', wsAjaxLoadBankStart, wsAjaxLoadBankError, 'wsAjaxLoadBankResponseSuccess()', 'wsAjaxLoadBankResponseError()');
         }
         function ws_AJAXSubscriptionEditBankStart(){}
         function ws_AJAXSubscriptionEditBankError(){}
         function ws_AJAXSubscriptionEditBankResponseError(){}

         function wsAjaxLoadBankStart(){}
         function wsAjaxLoadBankError(){}
         function wsAjaxLoadBankResponseSuccess(){}
         function wsAjaxLoadBankResponseError(){}
      </script>
   {/WS-OTP3(updateBankSubscription)}
</main>
...

 

5. Neues Template "Abo-Übersicht" (ws_subscription_manage.htm) im Kundenkonto

...
<body>
   <div id="subscriptionContent">
      {ST-Ajax}<WS-Ajax-subscriptionContent>{/ST-Ajax}
         Abonnements
         <!-- Notifications -->
         {MSG-Subscription_success}
            {MSG-Subscription_success(1)}Ihr Abonnement wurde erfolgreich abgeschlossen.{/MSG-Subscription_success(1)}
            {MSG-Subscription_success(2)}Ihr Abonnement wurde pausiert. Sie können das Abo jederzeit reaktivieren.{/MSG-Subscription_success(2)}
            {MSG-Subscription_success(3)}Ihr Abonnement ist wieder aktiv. Das nächste Lieferdatum entnehmen Sie bitte der Übersicht.{/MSG-Subscription_success(3)}
            {MSG-Subscription_success(4)}Ihr Abonnement wurde erfolgreich an Ihre Wünsche angepasst.{/MSG-Subscription_success(4)} 
            {MSG-Subscription_success(5)}Sie haben Ihr Abonnement gelöscht.{/MSG-Subscription_success(5)}
            {MSG-Subscription_success(6)}Ihre erste Abo - Bestellung wird bald durchgeführt.{/MSG-Subscription_success(6)}
            {MSG-Subscription_success(7)}Es wurde eine neue Bankverbindung für Ihre Abonnements festgelegt.{/MSG-Subscription_success(7)}
         {/MSG-Subscription_success}

         {MSG-Subscription_error}
            {MSG-Subscription_error(1)}Sie sind nicht angemeldet. Um ein Abo abschließen zu können, müssen Sie angmeldet sein. Bitte loggen Sie sich mit Ihren Zugangsdaten ein. Sollten Sie noch keinen Kundenaccount haben, registrieren Sie sich bitte.{/MSG-Subscription_error(1)}
            {MSG-Subscription_error(2)}Bitte prüfen Sie Ihre Eingaben. Die eingegebene Menge oder der Zeitraum Ihres Abos könnten fehlerhaft sein.{/MSG-Subscription_error(2)}  
            {MSG-Subscription_error(3)}Bitte reaktivieren Sie Ihr Abonnement, bevor Sie Änderungen daran vornehmen.{/MSG-Subscription_error(3)}  
            {MSG-Subscription_error(4)}Das ausgewählte Produkt ist kein Aboprodukt.{/MSG-Subscription_error(4)}  
            {MSG-Subscription_error(5)}Das ausgewählte Produkt ist kein Aboprodukt, da es aus einem Set von Produkten besteht.{/MSG-Subscription_error(5)}  
            {MSG-Subscription_error(6)}Bitte wählen Sie eine spezifische Produktvariante um das Abo abzuschließen.{/MSG-Subscription_error(6)}  
            {MSG-Subscription_error(7)}Das ausgewählte Produkt kann nicht gefunden werden.{/MSG-Subscription_error(7)}  
            {MSG-Subscription_error(8)}Ihre Abobestellung konnte nicht ausgeführt werden.{/MSG-Subscription_error(8)}  
         {/MSG-Subscription_error}

         Sie haben ~SUBS-Data~ Abonnements. Hier können Sie Ihre Abonnements ändern, pausieren und löschen.

         <!-- Adresse Details -->
         Lieferadresse
         Die Lieferung Ihrer Abonnements erfolgt an Ihre Rechnungsadresse:
         {A-FirstName}
            <div id="subscriptionAddress"></div>
         {/A-FirstName}
         <span data-toggle="modal" data-target="#modal-addressFields">Lieferadresse bearbeiten</span>

         <!-- Bank Details -->
         Ihre Bankverbindung
         {SUBS-FixedPaymentCodeUsed(4)}
            Ihre Abonnements werden mit folgender Bankverbindung bezahlt:
            <div id="subscriptionBankOverview"></div>
         {/SUBS-FixedPaymentCodeUsed(4)}
         <span data-toggle="modal" data-target="#modal-bankFields">Bankverbindung bearbeiten</span>

         <!-- Abonnierte Produkte -->
         {!SUBS-Data}
            Es befinden sich derzeit noch keine Produkte auf Ihrer Aboliste.
         {/!SUBS-Data}

         {SUBS-Data}
            Hier finden Sie eine Übersicht Ihrer Abonnements.
            <form action="~FORM-Subscription~" id="subscription" method="POST">
               {@SUBS-Data}
                  {SUBS-Data_state_ispaused}Abonnement pausiert{/SUBS-Data_state_ispaused}
                  Produkt
                  {PR-LoadData($SUBS-Data_PR_Number$,1)}                    
                     {PR-LargeImage}
                        <a href="~PR-DepVarLink~"><img src="~PR-LargeImage~" alt="~PR-Name_StripHtml~" /></a>
                     {/PR-LargeImage}
                  {/PR-LoadData($SUBS-Data_PR_Number$,1)}
                  ~SUBS-Data_PR_Name~

                  Lieferintervall
                  <div class="inputLabelFocus" data-placeholder="Lieferintervall">
                     <label for="~SUBS-CycleSelection_input~" class="control-label">Lieferintervall</label>
                     <select class="form-control" name="~SUBS-CycleSelection_input~" onchange="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(), 'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()')">
                        {@SUBS-CycleSelection_data}
                           <option value="~SUBS-CycleSelection_data_value~" ~SUBS-CycleSelection_data_selected~>~SUBS-CycleSelection_data_descr~</option>
                        {/@SUBS-CycleSelection_data}
                     </select>
                  </div>
                  Erste Lieferung
                  ~DC-DateTime_setunixtimestamp($SUBS-Data_nextorder_unixtimestamp$)~ ~DC-DateTime_day~. ~DC-DateTime_month~. ~DC-DateTime_year~

                  Menge
                  <div class="inputLabelFocus" data-placeholder="Menge">
                     <label for="~SUBS-Data_PR_Quantity_input~" class="control-label">Menge</label>
                     <input class="form-control" name="~SUBS-Data_PR_Quantity_input~" value="~SUBS-Data_PR_Quantity~" onblur="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(), 'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()')">
                  </div>

                  Gesamtpreis
                  ~SUBS-Data_PR_Price~ ~WS-CurrencySymbol~ * ~SUBS-Data_PR_Quantity~
                  {PR-LoadData($SUBS-Data_PR_Number$,1)}
                     ~DC-FPCurrentPrice_set($PR-Price$)~
                  {/PR-LoadData($SUBS-Data_PR_Number$,1)}
                  {!DC-FPCurrentPrice($SUBS-Data_PR_Price$)}
                     Preisänderung
                     Aktueller Preis: ~DC-FPCurrentPrice~ ~WS-CurrencySymbol~
                  {/!DC-FPCurrentPrice($SUBS-Data_PR_Price$)}

                  {SUBS-Data_state_isactive}aktiv{/SUBS-Data_state_isactive}
                  {SUBS-Data_state_isnew}aktiv{/SUBS-Data_state_isnew}
                  {SUBS-Data_state_ispaused}pausiert{/SUBS-Data_state_ispaused}
                  {SUBS-Data_state_istriggered}aktiv{/SUBS-Data_state_istriggered}

                  <button type="submit" name="~SUBS-Data_Buttonname~" value="~SUBS-Data_Buttonvalue_delete~" onClick="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(), 'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()', '~SUBS-Data_Buttonname~=~SUBS-Data_Buttonvalue_delete~')">löschen</button>
                  {SUBS-Data_Buttonvalue_pause}<button type="submit" name="~SUBS-Data_Buttonname~" value="~SUBS-Data_Buttonvalue_pause~" onClick="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(), 'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()', '~SUBS-Data_Buttonname~=~SUBS-Data_Buttonvalue_pause~')">pausieren</button>{/SUBS-Data_Buttonvalue_pause}
                  {SUBS-Data_Buttonvalue_resume}<button type="submit" name="~SUBS-Data_Buttonname~" value="~SUBS-Data_Buttonvalue_resume~" onClick="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(), 'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()', '~SUBS-Data_Buttonname~=~SUBS-Data_Buttonvalue_resume~')">aktivieren</button>{/SUBS-Data_Buttonvalue_resume}
               {/@SUBS-Data}
            </form>
         {/SUBS-Data}  
      {ST-Ajax}</WS-Ajax-subscriptionContent>{/ST-Ajax}
   </div>

   <!-- Adresse im Modal-Fenster ändern -->
   <div class="modal fade" id="modal-addressFields" tabindex="-1" role="dialog">
      <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content" id="modal-content-addressFields">
            <div class="modal-body">
               Adresse Bearbeiten
               <button type="button" data-dismiss="modal" aria-label="Close" onclick="wsManualModalClose();"><span aria-hidden="true">×</span></button>
               <div id="modal-body-addressFields"></div>
            </div>
         </div>
      </div>
   </div>

   <!-- Bankdetails im Modal-Fenster ändern -->
   <div class="modal fade" id="modal-bankFields" tabindex="-1" role="dialog">
      <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content" id="modal-content-bankFields">
            <div class="modal-body">
               Bankdetails Bearbeiten
               <button type="button" data-dismiss="modal" aria-label="Close" onclick="wsManualModalCloseBank();"><span aria-hidden="true">×</span></button>
               <div id="modal-body-bankFields"></div>
               <div id="bankManageIframe">
                  <iframe src="~WS-EnsureNextLinkContainsURLParams~~WS-BankManageLink~&otp3=updateBankSubscription" frameborder="0" allowfullscreen class="iframe" style="height:605px;width:100%"></iframe>
               </div>
               <span onclick="wsManualModalCloseBank();">Fertig</span>
            </div>
         </div>
      </div>
   </div>

   <!-- AJAX Funktionen -->
   <script>
      $(document).on("click","#modal-addressFields",function(e){
         if(!$(event.target).is("#modal-addressFields *")) {
            wsManualModalClose();
         }
      })

      $(document).on("click","#modal-bankFields",function(e){
         if(!$(event.target).is("#modal-bankFields *")) {
            wsManualModalClose();
         }
      })

      function wsManualModalClose(){
         $("#modal-addressFields").modal("hide");
      }

      function wsManualModalCloseBank(){
         $("#modal-bankFields").modal("hide");
         ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-BankManageLink~&otp3=updateBankSubscription', '~WS-Charset~', wsAjaxLoadBankStart, wsAjaxLoadBankError, 'wsAjaxLoadBankResponseSuccess()', 'wsAjaxLoadBankResponseError()');
      }

      function wsAjaxLoadAdrressStart(){}
      function wsAjaxLoadAdrressError(){}
      function wsAjaxLoadAdrressResponseSuccess(){}
      function wsAjaxLoadAdrressResponseError(){}
      function wsAjaxLoadAdrressSaveResponseSuccess(){}
      ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-AddrManageLink~&otp3=updateAddressSubscription', '~WS-Charset~', wsAjaxLoadAdrressStart, wsAjaxLoadAdrressError, 'wsAjaxLoadAdrressResponseSuccess()', 'wsAjaxLoadAdrressResponseError()');

      function wsAjaxLoadBankStart(){}
      function wsAjaxLoadBankError(){}
      function wsAjaxLoadBankResponseSuccess(){}
      function wsAjaxLoadBankResponseError(){}
      ws_AJAXloadTemplate('~WS-EnsureNextLinkContainsURLParams~~WS-BankManageLink~&otp3=updateBankSubscription', '~WS-Charset~', wsAjaxLoadBankStart, wsAjaxLoadBankError, 'wsAjaxLoadBankResponseSuccess()', 'wsAjaxLoadBankResponseError()');
   </script>
</body>
...