HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

AJAX Form

How would I have to do that? I want a module showing a form and on clicking the submit button, the form values should be posted to a pluginController_myRoutine_create($sender, $args) { // save input, return success message, and clean form.

Is there any class="Popup" like thing for the method/action of the form or would I have to code it myself in JavaScript?

If I make the button a link styled like a button, I would not get any further, I guess. Or is there a way to access the form data after I clicked a link a.Popup.Button? I haven't tested that by now, maybe that's a solution...

Best Answer

Answers

  • LincLinc Admin

    Are you asking about this feature we added to core last week? https://github.com/vanilla/vanilla/pull/3947

  • R_JR_J Admin

    Yes, exactly! But for 2.2, of course. Or, if you tell me Vanilla 2.3 is available next week, I'll promise I'll be patient o:)

  • LincLinc Admin

    That won't be in 2.3.

  • R_JR_J Admin

    Alright then: when will 2.4 be released? :p

    I see you've used a jquery plugin called popin. So I guess I would have to write my own js and there is no easy way of reusing this and that.

    Do you have a hint what would be the theory behind doing what I want to do? By now I assume it would be
    a) a js that starts onclick
    b) does an ajax call to my new method, posting the values I'd like to submit
    c) cleans the form
    d) opens a friendly informMessage to report success

    Well, it must be like that...

    Do you (just by chance) know how to fire up a informMessage from js? If not, I'll simply take a look at the sources myself.

  • LincLinc Admin

    I wasn't involved in it really so I don't have any great insights here, sorry.

    I was however having a idle thought about maybe skipping 2.4 and jumping us straight to 3.0 this winter tho. B) Depends how things go with API v2.

  • You can make anything popup by simply adding the Popup class. Even things that don't normally popup like a form. By putting a button to click and a # link around the item you want to popup .

    Let's say you have made an extra page where you added the form you want, like my Contact plugin. Now I want to make that popup instead of having to go to the page, I add a link to the page and give it the Popup class. Now the page will popup when I click the link.

    I think you can do the same thing with just calling the form itself to popup via a button. It could also be hidden via CSS and then displayed via button click.

  • R_JR_J Admin

    @hgtonight said:
    If you want to use form data, you will have to write your own JS handler. It is pretty easy and there is even some code you could look at how to do it: https://github.com/vanilla/vanilla/blob/039b814b4ee7f2954ccc4921ee799bcccdb4e5ef/js/global.js#L684-L713

    Thanks for the hint! I have hoped it would be easy, but I have also hoped it could be even easier ;)

  • R_JR_J Admin

    @Linc said:
    I was however having a idle thought about maybe skipping 2.4 and jumping us straight to 3.0 this winter tho. B) Depends how things go with API v2.

    With the shiny new dashboard (and maybe a corresponding theme?), a full fledged API and - if I have interpreted this correct - a more disentangled Garden/Vanilla, a new version number is well deserved!

    But I personally would use a major version step to risk backward incompatibilities. I guess that sooner or later some painful decisions must be made and if they are wrapped in a new version number, it would be easier to accept for users (at least that's what I guess)

  • edited July 2016

    This the file I use for the Contact plugin in case you are curious. Which lives in the core library for js files.

    jquery.gardenhandleajaxform.js

    (function($) {
       // This turns any form into a "post-in-place" form so it is ajaxed to save
       // without a refresh. The form must be within an element with the "AjaxForm"
       // class.
       $.fn.handleAjaxForm = function(options) {
          var handle = this;
          $(this).find('form').each(function() {
             options = $.extend({
                frm:  this,
                data: { 'DeliveryType' : 'ASSET', 'DeliveryMethod' : 'JSON' },
                dataType: 'json',
                beforeSubmit: function(frm_data, frm) {
                   options.frm = frm;
                  // Add a spinner
                  var btn = $(frm).find('input.Button:last');
                  if ($(btn).parent().find('span.Progress').length == 0) {
                     $(btn).after('<span class="Progress">&#160;</span>');
                  }
                },
                success: function(json, status, $frm) {
                   json = $.postParseJson(json);
    
                   if (json.FormSaved == true) {
                      gdn.inform(json);
                      if (json.RedirectUrl) {
                         setTimeout("document.location='" + json.RedirectUrl + "';", 300);
                      } else if(json.DeliveryType == 'ASSET') {
                         $frm.parents($(handle).selector).html(json.Data);
                      } else {
                         // Remove the spinner if not redirecting...
                         $('span.Progress').remove();
                      }
                   } else {
                      // Check to see if a target has been specified for the data.
                      if(json.Target) {
                         $(json.Target).html(json.Data);
                      } else if(json.DeliveryType == 'MESSAGE') {
                         gdn.inform(json.Data, false);
                         $frm.find('span.Progress').remove();
                      } else {
                         $frm.parents($(handle).selector).html(json.Data);
                      }
                   }
                   // If there are additional targets in the result then set them now.
                   if(json.Targets) {
                      for(var i = 0; i < json.Targets.length; i++) {
                         var item = json.Targets[i];
                         if(item.Type == 'Text') {
                            $(item.Target).text($.base64Decode(item.Data));
                         } else {
                            $(item.Target).html($.base64Decode(item.Data));
                         }
                      }
                   }
    
                   // Re-attach the handler
                   $($(handle).selector).handleAjaxForm(options);
                 }
             }, options || {});
    
             $(this).ajaxForm(options);
          });
       }
    })(jQuery);
    
  • R_JR_J Admin

    I've ended with this short script:

    $( ".BoxQuickDiscussion form" ).submit(function( event ) {
        event.preventDefault();
    
        var elName = document.getElementsByName('QuickDiscussionName')[0];
        var elBody = document.getElementsByName('QuickDiscussionBody')[0];
    
        // Send the data using post
        var posting = $.post(
            this.getAttribute('action'),
            {
                Name: elName.value,
                Body: elBody.value,
                TransientKey: gdn.definition('TransientKey')
            }
        );
        posting.done(function( data ) {
            response = $.parseJSON(data);
    
            gdn.informMessage(response.Message);
    
            elName.value = '';
            elBody.value = '';
        });
    });
    

    Turned out I didn't need much Vanilla magic at all. It was just a simple AJAX call.

Sign In or Register to comment.