Row Custom Action with User input Dialog (v2023)

ListOptions_Rendered and Row_CustomAction are very useful events in PHPMaker.
Below is an example of carrying out a custom action that brings up a user input field that passes a value to the Custom Action. It uses the preConfirm
function of Sweetalerts 2 to capture the value(s) entered and passes it to the server. The value(s) are captured using $_POST on the server side

  1. List page-> ListOptions_Load
      $opt = &$this->ListOptions->Add("my_menu"); // Add Custom Link
      $opt->OnLeft = TRUE; // Link on left
  1. List page-> ListOptions_Rendered
     $this->ListOptions->Items["my_menu"]->Body ="<div class='sub-button shadow'>
            <a class='btn-success btn-fab' id='restock' value=".urlencode($this->description->CurrentValue)." href='#' onclick=\" Swal.fire({
                    title: 'RESTOCK',
                    text: '".$this->description->CurrentValue."',
                    input: 'number',
                    inputPlaceholder: 'How many?',
                    showCancelButton: true,
                    confirmButtonText: 'Restock',
                    showLoaderOnConfirm: true,
                            preConfirm: (pqty) => {
                                ew.submitAction(event, {f:'".CurrentTableName()."', action: 'myupdate', method: 'ajax', data: { qty: pqty}, key: " . $this->KeyToJson(true) . ", 
                    success: refreshTable})
                            }
                });\"'>
				<i class='bi bi-box-seam'></i>
            </a>
          </div>";
  1. List page-> Row_CustomAction
function Row_CustomAction($action, $row)
{
    $qty = $_POST["qty"];
    // Return false to abort
    if ($action == "myupdate") { // Check action name
		$rsnew = ["in_stock" => ($row["in_stock"]+$qty)];// Array of field(s) to be updated
		$result = $this->update($rsnew, "id = " . $row["id"]); // Update the current record only 
		if (!$result) { // Failure
			$this->setFailureMessage("Action failed on " . $row["description"]);
			return FALSE; // Abort and rollback
		} else if ($this->SelectedIndex == $this->SelectedCount) { // Last row
			$this->setSuccessMessage("Action on ".$row["description"].", succeeded.");                 
		}
		 return TRUE; 
	}
}

It does not work properly, since you have not included the code of refreshTable function.

mobhar wrote:

It does not work properly, since you have not included the code of > refreshTable > function.

Sorry about that.

Add the code below to Client Scripts->Global->Pages with header/footer->Global Code

function refreshTable(){
    var myform = document.querySelector('.ew-list-form')//('.ew-grid-middle-panel')
    var fid = "#"+myform.getAttribute("id") 
    $(fid).load(location.href+" "+fid+">*", "")
    
}

The last line of the code is in JQuery. Still have figured out how to convert it to Javascript.

Or you may simply use this code instead:

refreshTable = function() {
    window.location.reload();
}

Thank you for this.
In my case, I wanted to do a partial page refresh with the original code.

mobhar wrote:

Or you may simply use this code instead:

refreshTable = function() {
window.location.reload();
}

>

Please be careful as this reposts the previous call with data and may cause duplicate entry!The solution here is preferred: https://stackoverflow.com/questions/570015/how-do-i-reload-a-page-without-a-postdata-warning-in-javascriptOr, if you want to update only the current row after ajax call then this method may be combined with that of Niijimasama to give:

> ```text
window.complete_script = function (msg) {
    ew.alert(msg).then(function(result){ //".then" forces alert to wait till close, then only refresh page!
        var myform = document.querySelector('.ew-list-form'); //('.ew-grid-middle-panel')
        var fid = "#"+myform.getAttribute("id");
        if ( window.history.replaceState ) {
            window.history.replaceState( null, null, window.location.href );
        }
        $(fid).load(location.href+" "+fid+">*", "")
    });
}