Skip Navigation

[Resolved] Custom Search Update Using AJAX Not Working After the First Time

This thread is resolved. Here is a description of the problem and solution.

Problem: I am updating a custom search View using AJAX by triggering a click event on the submit button using custom JavaScript. The View updates once, but then subsequent clicks do not update the results.

Solution: Eliminate other blocking JavaScript errors.

This support ticket is created 6 years, 5 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

No supporters are available to work today on Toolset forum. Feel free to create tickets and we will handle it as soon as we are online. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 11 replies, has 3 voices.

Last updated by jesseB-4 6 years, 5 months ago.

Assisted by: Christian Cox.

Author
Posts
#916761

Hello, I'm using Toolset Views to display orders on my client's kitchen display screen online. The view "Kitchen Orders" is a custom search view with a hidden filter and a search button with the CSS class of "autoClickFSb". This view is triggered by the JS code "$('.autoClickFSb').trigger('click')" to update the search results after an order's status is changed by our own custom AJAX calls.

The View AJAX update works once and afterward will not update to reflect the latest changes. For example:
Order #1110 is a Processing order. Once I change its status from Processing to Packaged, the View updates and displays it as a Packaged order. When I update it a second time from Packaged to Completed (this status is filtered out of the View and thus removed entirely from the KDS), the View doesn't update.

From my understanding, this should always work. On inspection, the AJAX call for updating the view gives out a 200 OK despite not updating. Is it because it is already displaying the *new* search results when I try to update a second time?

Any help on this would be appreciated.

#916901

I assume you should re-fire your custom JS code on certain events, such as when the View AJAX Search completes it's job.
This can be done in the View's Custom Search editor, just under the HTML section there is the JS editor where you can add your own code to our Hooks, which are all provided by a GUI (Frontend Events).

Whatever code you run, you can re-run it at each of those events you are provided with there.

That should help you to make sure your custom queries are run each Time the View updates it's results (or other events)

#917533

Hello Beda, thank you for your response!

My custom JS has the following codes to update the Order status:

/* Package Order AJAX */
$(".package-btn").click(function () {
  var order_id = $(this).attr('order_id');
  //alert("Update Order No. " + order_id + " to Packaged");
  $('div.modal-order').css('background-color', 'rgba(0,0,0,0.8)');
  $.ajax({
  	type: 'POST',
    	url: '<em><u>hidden link</u></em>',
      data: {
      	'order_id': order_id,
        'action': 'packageOrderAJAX' // Name of AJAX method called in WordPress
      },
      headers : {
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
      },
      dataType: "json",
      success: function (result) {
  			//alert(result);
        success(document.getElementById("myModal"));
      },
      error: function () {
        //alert("An error has occurred!");
        failure(document.getElementById("myModal"));
      }
  });
});

And the following codes to trigger the View to update on success:

// On Success
function success(obj) {
  var orig = obj.style.backgroundColor;
  obj.style.backgroundColor = "rgba(95, 186, 125, 0.8)";
  setTimeout(function() {
  	obj.style.backgroundColor = orig;
  }, 1500);
  alert("Order updated successfully! Please wait a moment while the screen updates.");
  /* Closes order modal */
  var modal = document.getElementById('myModal');
  var modalOrder = document.getElementsByClassName('order-modal');
  for (var i = 0; i < modalOrder.length; i++) {
  	modalOrder[i].style.display="none";
  }
  setTimeout(function () {
  	modal.style.display = 'none';
  }, 1600);
  // Triggers View to update frontend values
  $('.autoClickFSb').trigger('click');
}

I had my custom JS, including those functions, in the JS Editor inside of:

jQuery( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) {.../}

But the View still doesn't update a second time. What am I doing wrong? Do I need to use a different front end event handler?

#917626

Can you add some console logs? First in the success callback:

function success(obj) {
  var orig = obj.style.backgroundColor;
  ...
  // Triggers View to update frontend values
  console.log('triggers: ', $('.autoClickFSb').length); 
  $('.autoClickFSb').trigger('click');
}

Also in the click handler:

$(".package-btn").click(function () {
  console.log('click');
  var order_id = $(this).attr('order_id');
  ...

Then run through the process again with the browser console open and report the results here.

#917658
Screen Shot 2018-06-25 at 4.07.11 PM.png

Hello Christian, thank you for responding. Please find an attached image of the Console log. Note that the first error is caused by Google Maps API. The second error is caused by the Modal's disappearance after an order has been updated.

The affected code I believe is:

    // Get the closing trigger
    var closingBtn = document.getElementsByClassName('close-order-btn');
    var close = closingBtn[0];
    
    // Close modal by clicking the close button
    close.onclick = function() {
      var modalOrder = document.getElementsByClassName('order-modal');
      for (var i = 0; i < modalOrder.length; i++) {
          modalOrder[i].style.display="none";
      }
      modal.style.display = 'none';
    }

    // Close modal by clicking outside of modal
    window.onclick = function(event) {
      if (event.target == modal) {
        var modalOrder = document.getElementsByClassName('order-modal');
        for (var i = 0; i < modalOrder.length; i++) {
            modalOrder[i].style.display="none";
        }
        modal.style.display = 'none';
      }
    }

This controls the closing behaviour of the Modal.

I first Packaged an order before Reverting it; there's no second "click" in the logs because I didn't put a second "console.log('click');" in the Revert Order function.

#917697

Okay that looks fine, you can remove those log statements.
When I update it a second time from Packaged to Completed (this status is filtered out of the View and thus removed entirely from the KDS), the View doesn't update.
I first Packaged an order before Reverting it; there's no second "click" in the logs because I didn't put a second "console.log('click');" in the Revert Order function.
I'm trying to understand the terminology: is the update from Packaged to Completed the same as "Revert"?
What code triggers the update from Packaged to Completed?

#917924

Sorry for the confusing terms, let me explain.

There are three order status: Processing, Packaged, and Completed. As I said, Completed is filtered out of the View because it is "finalized". The three buttons are:

Package Order: Processing -> Packaged
Complete Order: Packaged -> Completed
Revert Order: Packaged -> Processing

The JS code for Packaged to Completed are:

/* Complete Order AJAX */
$(".complete-btn").click(function () {
  var order_id = $(this).attr('order_id');
  var finalizePrompt = confirm("Are you sure you want to finalize this order? You cannot see or edit this order afterward.");
  if (finalizePrompt == true) {
    //alert("Update Order No. " + order_id + " to Completed");
    $('div.modal-order').css('background-color', 'rgba(0,0,0,0.8)');
    $.ajax({
      type: 'POST',
        url: '<em><u>hidden link</u></em>',
        data: {
          'order_id': order_id,
          'action': 'completeOrderAJAX' // Name of AJAX method called in WordPress
        },
        headers : {
          'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
        },
        dataType: "json",
        success: function (result) {
          //alert(result);
          success(document.getElementById("myModal"));
        },
        error: function () {
          //alert("An error has occurred!");
          failure(document.getElementById("myModal"));
        }
    });
  } else {
    cancelled(document.getElementById("myModal"));
  }
});

The Success function is the one in my second post.
And the PHP code:

function completeOrderAJAX() {

    // retrieve post_id, and sanitize it to enhance security
    $order_id = intval($_POST['order_id'] );

    // Check if the input was a valid integer
    if ( $order_id == 0 ) {
        echo "Invalid Input";
        die();
    }

	  $order = new WC_Order($order_id);
	  if (!empty($order)) {
		$order->update_status( 'completed' );
		//echo 'order completed';
		echo json_encode('Order Completed!');
		die();
	  }

    //echo 'Invalid order';
  	echo json_encode('Invalid order');
    die();

}
add_action( 'wp_ajax_nopriv_completeOrderAJAX', 'completeOrderAJAX' );
add_action( 'wp_ajax_completeOrderAJAX', 'completeOrderAJAX' ); 

Edit: Also, I don't know if I really need to include the custom AJAX JS which also has the View update trigger inside the JS Editor below the Custom Search Filter. The JS in Customizer > Custom > Edit Global JS gets called anyway.

Let me know if you need anything or access to the live website. Thank you!

#917947

I have the access credentials you provided above, can you set me up with a test order I can work with? I would like to start with a Processing Order, then be able to Package, Revert, Package again, and Complete the Order, but I don't want to disrupt the live site operations.

#918036

The link to the KDS if you don't have it is hidden link

I've set up Order No. 5099 for you to use. You can edit the order from the backend by navigating to WP Backend > WooCommerce > Orders.

Order 4904, 4910, 4927, and 5010 are also all existing test orders, so if you need more you can use them. I'll refrain from using the KDS while you're on.

#918076

I just logged in as Mike using the login credentials you provided in the first post. My User doesn't have access to Orders or the Toolset menu in wp-admin, so I can't do much digging.

In the KDS, I clicked in Order 5099 to display the popup. In that popup, I clicked "Package Order". I saw two alerts, then View of Orders updated and now Order 5099 is no longer displayed in the KDS. Did I go through the steps incorrectly? The order status said "wc-processing" on the KDS when I first logged in, so I thought this would change the order status to Packaged. However, the Order was removed from the main View - which I thought would only happen when the status changed to Completed.

At any rate, then I refreshed the page. I began the process again with Order 4904 and had the same results. After clicking "Package Order" the Order was no longer displayed in the main KDS View. Then I packaged Order 4927 without refreshing the page first. This time, Order 4927 remained visible after the main View was updated.

So I'm confused about the process based on the instructions you gave earlier.

Also, I don't know if I really need to include the custom AJAX JS which also has the View update trigger inside the JS Editor below the Custom Search Filter. The JS in Customizer > Custom > Edit Global JS gets called anyway.
I think I see what you're talking about. There is no need to re-initialize the close or package button click handlers from within the js_event_wpv_parametric_search_results_updated event callback if the original close or package buttons are not removed from the DOM when the search results are updated.

If you'd like to provide me with different login credentials so I can check the Orders and Views, please use the private reply fields here.

#918102
#918124

Okay the second error we were seeing in the console appears to be part of the problem. I added a conditional checking whether or not there is a close button, which prevents the error. Now I can see the alert "View has been updated!" after triggering the second click.

    var closingBtn = document.getElementsByClassName('closing-order-btn');
    var close = closingBtn[0];

    // Close modal by clicking the close button
    if(close){
      close.onclick = function() {
        modal.style.display = 'none';
      }
    }

I can immediately see that the behavior has changed, but it looks like now some update is being triggered twice, I'm seeing duplicate alerts.

#918400

Hello Christian,

The duplicate actions you saw were because I put the custom AJAX functions in both Customizer's Global JS and View's custom search filter JS editor. I went ahead and removed them in the latter and placed your conditional checking in Global JS. The View update using AJAX is now working!

Now I just need to link the Modal view with the Kitchen Orders view in order for it to also update. Thank you once again Christian!