iNoize

Handling Ajax form with jQuery.post

Recommended Posts

Hello, 

I try to realize some booking form via jQuery.post method. 

It works to send the data to the book.php file. 
Whats next ? How to handle the data right. this is the JS code 

 

jQuery.post("./book.php",{ xx_name: name, xx_email: email, xx_date: date, xx_time: time, xx_message:message, xx_contact: contact}, function(data) {
jQuery(".book_online_form .returnmessage").append(data);//Append returned message to message paragraph
									
if(jQuery(".book_online_form .returnmessage span.book_error").length){
     jQuery(".book_online_form .returnmessage").slideDown(500).delay(2000).slideUp(500);		
}else{
    jQuery(".book_online_form .returnmessage").append("<span class='book_success'>"+ success +"</span>")
    jQuery(".book_online_form .returnmessage").slideDown(500).delay(4000).slideUp(500);
    setTimeout(function(){  $.magnificPopup.close() }, 5500);
}
									
if(data==""){
jQuery(".book_online_form")[0].reset();//To reset form fields on success
}
});

It works for me i get the data but what now ? how to handlte this right ? 
this is the post.php 
 

<?php  

include("./index.php"); 
// include header markup 
$sent = false;
$error = '';
$emailTo = 'my@email.here'; // or pull from PW page field

// sanitize form values or create empty
$form = array(
    'fullname' => $sanitizer->text($input->post->name),
    'email' => $sanitizer->email($input->post->email),
    'comments' => $sanitizer->textarea($input->post->message),
    ); 

print "CONTENT_TYPE: " . $_SERVER['CONTENT_TYPE'] . "<BR />";
$data = file_get_contents('php://input');   // Dont really know what happens but it works 
print "DATA: <pre>";
var_dump($data);
var_dump($_POST);
var_dump($form);
print "</pre>";


if($input->post->submit) {

   $name = $_REQUEST['xx_name'];  
   echo "Welcome 1". $name; // DONT WORK 

 }else{

 	 echo "Something is wrong on the submit ";
 }

if( $_REQUEST["xx_name"] ) {

   $name = $_REQUEST['xx_name'];
   echo "Welcome 2". $name;   //    WORK 
}

I have attached the output. 

how to act with the pw $input->post->submit and the form array for example ?? 

post-957-0-72864000-1448354947_thumb.jpg

Share this post


Link to post
Share on other sites

Not sure, but is it even possible to refer to $input->post->variable without posting to a ProcessWire page? You should post the data to a ProcessWire page like /book/ (which has the book.php file as its template).

Share this post


Link to post
Share on other sites

@Ferdi 

it works because i bootstraped pw with include("./index.php"); 

I guess you don't POST the name submit.

So $input->post->submit is not there, resulting in a false 

that was the solution. I dont know its the best solution but i solved this with 

ajaxContentAdded: function(){
jQuery(".book_submit").click(function(){
var name 		= jQuery(".book_online_form #name").val();
var email 		= jQuery(".book_online_form #email").val();
var date 		= jQuery(".book_online_form #reservation-date").val();
var time 		= jQuery(".book_online_form #reservation-time").val();
var message 	= jQuery(".book_online_form #message").val();
var contact 	= jQuery(".book_online_form #contact").val();
var submit      = 'submit';
var success     = jQuery(".book_online_form .returnmessage").data('success');
jQuery(".book_online_form .returnmessage").empty(); //To empty previous error/success message.
							//checking for blank fields	
							if(name==''||email==''||contact==''||date==''||message==''){
								//alert("Please Fill Required Fields"); 
								jQuery('div.empty_notice').slideDown(500).delay(2000).slideUp(500);
							}
							else{
								// Returns successful data submission message when the entered information is stored in database.
								jQuery.post("./book.php",{ xx_submit:submit, xx_name: name, xx_email: email, xx_date: date, xx_time: time, xx_message:message, xx_contact: contact}, function(data) {

									
									jQuery(".book_online_form .returnmessage").append(data);//Append returned message to message paragraph
									
									
									if(jQuery(".book_online_form .returnmessage span.book_error").length){
										jQuery(".book_online_form .returnmessage").slideDown(500).delay(2000).slideUp(500);		
									}else{
										jQuery(".book_online_form .returnmessage").append("<span class='book_success'>"+ success +"</span>")
										jQuery(".book_online_form .returnmessage").slideDown(500).delay(4000).slideUp(500);
										 //setTimeout(function(){  $.magnificPopup.close() }, 5500);
									}
									
									if(data==""){
										jQuery(".book_online_form")[0].reset();//To reset form fields on success
									}
									
								});
							}
						 
						});

and in the php coe if($input->post->xx_submit) { 

Thanks 

Share this post


Link to post
Share on other sites

Yes you are right,

I don't understand why it's here so broken view. I use SublimeText and there seems to be ok. If I paste it to the Forum than I have this result. Don't understand why ?

Share this post


Link to post
Share on other sites

It seems your jQuery Post method is not working. In such situations you can apply jQuery .Deferred() which are  chainable utility object with methods to register multiple callbacks. See this jQuery Post method example where they have applied the .done() and .fail() Deferred events in the Post method. 

On the .done() show the returned value and on the .fail() you can find out the error message which you get like this:

Spoiler

alert("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText);

I think it will help you.

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By louisstephens
      So I was going to build a todo tracking app for myself to test/broaden my knowledge of processwire, and so far it has been taxing 😓.  My Site structure is:
      - Project One - Phase One - Task - Task - Task - Phase Two - Task - Task - Task So far it was pretty easy, I can easily foreach through the Project and get the phases with their tasks. However, it gets a bit muddled when I have more than one project as I was trying to have a dashboard where the content switches out to the selected project as opposed to accessing each project via their own url. How would yall handle this?
      My next hurdle is each task has a select field (for project status) that I want to update via ajax (for the smooth transitioning).
      Scenario: You finish a task, change the option from "new" to "completed", and an onclick changes the status drop down background to green (which I have working), but then posts/saves a field on the backend to the new option.
       
      I have a page called "Actions" set up with url segments using
      if ($config->ajax && $input->urlSegment1 == 'change-status') { //save update field on admin } However, I am a little fuzzy on how to actually pass the current page along with the new selected status to actually update the page (task). I guess I am not very far into my endeavor. Any help would be greatly appreciated.
    • By j00st
      Hi all,

      I've set up a filter on my product-page, which I then use to...filter my products!
      – I've got pagination set up, and 30 items per page.
      – When I active the filter it works perfectly (in my opinion).
       
      Here's what I'm struggling with though:
      When I'm on another page (filtered as well/or the total overview) and I put my GET request in for the filter,
      it gives back the result, but still with the page-number there. In some cases, this is no problem – like a A-Z or Z-A filter,
      but others (say, per location) I might have less pages.
      Visual/code ref: (I DO have 3 pages of authors, but I don't have 3 pages from London)
      url: books/page3?author=ascending url: books/page3?studio=london  
      The current setup for my pages that get rendered are as follows:
      $allbooks = $pages->find("template=book, sort=$sort, $q, $tagged, $select_studio, start=0, limit=$limit"); As you can see I have the start=0 in there, but I read that's for the start of the pagination, not so much where it'll drop me in the search results.
      $q, $tagged and $select_studio are all empty values, unless they're returned from the GET request
      To repeat it, in it's most simplest form:
      When I click a filter, and a GET request is done, I want to 'reset' the page-number to 0, and get my results...
      Perhaps I'm missing something obvious, but I'd be really grateful to have your input.
    • By louisstephens
      So I have a project where multiple pages are sending POST data to 1 single template page.  All was working well (well, at least with one ajax post), but now I have hit a stumbling block. I figured  the "best" way to handle the request were to use url segments and then use the following in the status page:
      if ($config->ajax && $input->urlSegment1 == 'add-bookmark') { // some code here } However, this doesnt seem to really work (as I assume the the request isnt being posted to /status/ but rather to /status/add-bookmark/). What is the best way to actually handle this?
    • By louisstephens
      Currently, I have a page set up listing all child pages using a foreach loop and outputting some information (thus far, it is all gravy). However, I ran into a slight problem. I have a "button" on each item being rendered that when clicked needs to send the page id to another page for processing via ajax. I thought I could just save the item id like :
      <?php $itemId = $item->id; ?> And then encoding it below in my javascript:
      var itemId = <?php echo json_encode($itemId); ?>; var data = { itemId: itemId, }; $.ajax({ type: "POST", url: "/intra/status/", data: data, success: function(){ console.log(itemId); } }); However, it is only posting the last page's id rendered by the foreach. Have I just overlooked something simple on this?
    • By Noel Boss
      Page Query Boss
      Build complex nested queries containing multiple fields and pages and return an array or JSON. This is useful to fetch data for SPA and PWA.
      You can use the Module to transform a ProcessWire Page or PageArray – even RepeaterMatrixPageArrays – into an array or JSON. Queries can be nested and contain closures as callback functions. Some field-types are transformed automatically, like Pageimages or MapMarker.
      Installation
      Via ProcessWire Backend
      It is recommended to install the Module via the ProcessWire admin "Modules" > "Site" > "Add New" > "Add Module from Directory" using the PageQueryBoss class name.
      Manually
      Download the files from Github or the ProcessWire repository: https://modules.processwire.com/modules/page-query-builder/
      Copy all of the files for this module into /site/modules/PageQueryBoss/ Go to “Modules > Refresh” in your admin, and then click “install” for the this module. Module Methods
      There are two main methods:
      Return query as JSON
      $page->pageQueryJson($query); Return query as Array
      $page->pageQueryArray($query); Building the query
      The query can contain key and value pairs, or only keys. It can be nested and 
      contain closures for dynamic values. To illustrate a short example:
      // simple query: $query = [ 'height', 'floors', ]; $pages->find('template=skyscraper')->pageQueryJson($query); Queries can be nested, contain page names, template names or contain functions and ProcessWire selectors:
      // simple query: $query = [ 'height', 'floors', 'images', // < some fileds contain default sub-queries to return data 'files' => [ // but you can also overrdide these defaults: 'filename' 'ext', 'url', ], // Assuming there are child pages with the architec template, or a // field name with a page relation to architects 'architect' => [ // sub-query 'name', 'email' ], // queries can contain closure functions that return dynamic content 'querytime' => function($parent){ return "Query for $parent->title was built ".time(); } ]; $pages->find('template=skyscraper')->pageQueryJson($query); Keys:
      A single fieldname; height or floors or architects 
      The Module can handle the following fields:
      Strings, Dates, Integer… any default one-dimensional value Page references Pageimages Pagefiles PageArray MapMarker FieldtypeFunctional A template name; skyscraper or city
      Name of a child page (page.child.name=pagename); my-page-name A ProcessWire selector; template=building, floors>=25
      A new name for the returned index passed by a # delimiter:
      // the field skyscraper will be renamed to "building": $query = ["skyscraper`#building`"]  
      Key value pars:
      Any of the keys above (1-5) with an new nested sub-query array:
      $query = [ 'skyscraper' => [ 'height', 'floors' ], 'architect' => [ 'title', 'email' ], ]  
      A named key and a closure function to process and return a query. The closure gets the parent object as argument:
      $query = [ 'architecs' => function($parent) { $architects = $parent->find('template=architect'); return $architects->arrayQuery(['name', 'email']); // or return $architects->explode('name, email'); } ] Real life example:
      $query = [ 'title', 'subtitle', // naming the key invitation 'template=Invitation, limit=1#invitation' => [ 'title', 'subtitle', 'body', ], // returns global speakers and local ones... 'speakers' => function($page){ $speakers = $page->speaker_relation; $speakers = $speakers->prepend(wire('pages')->find('template=Speaker, global=1, sort=-id')); // build a query of the speakers with return $speakers->arrayQuery([ 'title#name', // rename title field to name 'subtitle#ministry', // rename subtitle field to ministry 'links' => [ 'linklabel#label', // rename linklabel field to minlabelistry 'link' ], ]); }, 'Program' => [ // Child Pages with template=Program 'title', 'summary', 'start' => function($parent){ // calculate the startdate from timetables return $parent->children->first->date; }, 'end' => function($parent){ // calculate the endate from timetables return $parent->children->last->date; }, 'Timetable' => [ 'date', // date 'timetable#entry'=> [ 'time#start', // time 'time_until#end', // time 'subtitle#description', // entry title ], ], ], // ProcessWire selector, selecting children > name result "location" 'template=Location, limit=1#location' => [ 'title#city', // summary title field to city 'body', 'country', 'venue', 'summary#address', // rename summary field to address 'link#tickets', // rename ticket link 'map', // Mapmarker field, automatically transformed 'images', 'infos#categories' => [ // repeater matrix! > rename to categories 'title#name', // rename title field to name 'entries' => [ // nested repeater matrix! 'title', 'body' ] ], ], ]; if ($input->urlSegment1 === 'json') { header('Content-type: application/json'); echo $page->pageQueryJson($query); exit(); } Module default settings
      The modules settings are public. They can be directly modified, for example:
      $modules->get('PageQueryBoss')->debug = true; $modules->get('PageQueryBoss')->defaults = []; // reset all defaults Default queries for fields:
      Some field-types or templates come with default selectors, like Pageimages etc. These are the default queries:
      // Access and modify default queries: $modules->get('PageQueryBoss')->defaults['queries'] … public $defaults = [ 'queries' => [ 'Pageimages' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus', ], 'Pagefiles' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'filesize', 'filesizeStr', 'hash', ], 'MapMarker' => [ 'lat', 'lng', 'zoom', 'address', ], 'User' => [ 'name', 'email', ], ], ]; These defaults will only be used if there is no nested sub-query for the respective type. If you query a field with complex data and do not provide a sub-query, it will be transformed accordingly:
      $page->pageQueryArry(['images']); // returns something like this 'images' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus'=> [ 'top', 'left', 'zoom', 'default', 'str', ] ]; You can always provide your own sub-query, so the defaults will not be used:
      $page->pageQueryArry([ 'images' => [ 'filename', 'description' ], ]); Overriding default queries:
      You can also override the defaults, for example
      $modules->get('PageQueryBoss')->defaults['queries']['Pageimages'] = [ 'basename', 'url', 'description', ]; Index of nested elements
      The index for nested elements can be adjusted. This is also done with defaults. There are 3 possibilities:
      Nested by name (default) Nested by ID Nested by numerical index Named index (default):
      This is the default setting. If you have a field that contains sub-items, the name will be the key in the results:
      // example $pagesByName = [ 'page-1-name' => [ 'title' => "Page one title", 'name' => 'page-1-name', ], 'page-2-name' => [ 'title' => "Page two title", 'name' => 'page-2-name', ] ] ID based index:
      If an object is listed in $defaults['index-id'] the id will be the key in the results. Currently, no items are listed as defaults for id-based index:
      // Set pages to get ID based index: $modules->get('PageQueryBoss')->defaults['index-id']['Page']; // Example return array: $pagesById = [ 123 => [ 'title' => "Page one title", 'name' => 123, ], 124 => [ 'title' => "Page two title", 'name' => 124, ] ] Number based index
      By default, a couple of fields are transformed automatically to contain numbered indexes:
      // objects or template names that should use numerical indexes for children instead of names $defaults['index-n'] => [ 'Pageimage', 'Pagefile', 'RepeaterMatrixPage', ]; // example $images = [ 0 => [ 'filename' => "image1.jpg", ], 1 => [ 'filename' => "image2.jpg", ] ] Tipp: When you remove the key 'Pageimage' from $defaults['index-n'], the index will again be name-based.
       
      Help-fill closures & tipps:
      These are few helpfill closure functions you might want to use or could help as a
      starting point for your own (let me know if you have your own):

      Get an overview of languages:
          $query = ['languages' => function($page){         $ar = [];         $l=0;         foreach (wire('languages') as $language) {             // build the json url with segment 1             $ar[$l]['url']= $page->localHttpUrl($language).wire('input')->urlSegment1;             $ar[$l]['name'] = $language->name == 'default' ? 'en' : $language->name;             $ar[$l]['title'] = $language->getLanguageValue($language, 'title');             $ar[$l]['active'] = $language->id == wire('user')->language->id;             $l++;         }         return $ar;     }]; Get county info from ContinentsAndCountries Module
      Using the [ContinentsAndCountries Module](https://modules.processwire.com/modules/continents-and-countries/) you can extract iso
      code and names for countries:
          $query = ['country' => function($page){         $c = wire('modules')->get('ContinentsAndCountries')->findBy('countries', array('name', 'iso', 'code'),['code' =>$page->country]);         return count($c) ? (array) $c[count($c)-1] : null;     }]; Custom strings from a RepeaterTable for interface
      Using a RepeaterMatrix you can create template string for your frontend. This is
      usefull for buttons, labels etc. The following code uses a repeater with the
      name `strings` has a `key` and a `body` field, the returned array contains the `key` field as,
      you guess, keys and the `body` field as values:
          // build custom translations     $query = ['strings' => function($page){         return array_column($page->get('strings')->each(['key', 'body']), 'body', 'key');     }]; Multilanguage with default language fallback
      Using the following setup you can handle multilanguage and return your default
      language if the requested language does not exist. The url is composed like so:
      `page/path/{language}/{content-type}` for example: `api/icf/zurich/conference/2019/de/json`
       
          // get contenttype and language (or default language if not exists)     $lang = wire('languages')->get($input->urlSegment1);     if(!$lang instanceof Nullpage){         $user->language = $lang;     } else {         $lang = $user->language;     }     // contenttype segment 2 or 1 if language not present     $contenttype = $input->urlSegment2 ? $input->urlSegment2 : $input->urlSegment1;     if ($contenttype === 'json') {         header('Content-type: application/json');         echo $page->pageQueryJson($query);         exit();     } Debug
      The module respects wire('config')->debug. It integrates with TracyDebug. You can override it like so:
      // turns on debug output no mather what: $modules->get('PageQueryBoss')->debug = true; Todos
      Make defaults configurable via Backend. How could that be done in style with the default queries?
      Module in alpha Stage: Subject to change
      This module is in alpha stage … Query behaviour (especially selecting child-templates, renaming, naming etc)  could change