File field validation in Tickets

There is a ticket module (https://modstore.pro/packages/users/tickets).
The form for adding a ticket looks like this:

<form class="well create" enctype="multipart/form-data" method="post" action="" id="ticketForm">
<div class="col-md-12 col-sm-12">
<label for="pagetitle">Name</label>
<input type="text" id="pagetitle" name="pagetitle" placeholder="Name" class="form-control" value=""/>
<span class="error"></span>
</div> 
    .... 
<div class="file-upload">
<div class="ticket-form-files">
[[+files]]
</div>
</div>
<div class="form-group">
<div class="col-sm-6">
<button class="btn btn-lg pull-left draft" name="draft" type="submit"><i class="fa fa-check"></i> Send</button>
</div>
<div class="col-sm-6">
<button class="btn btn-lg pull-left draft" type='button' onclick="clearSearchForms()"><i class="fa fa-trash-o"></i> Clear form</button>        	
</div>	
</div>
</form>

Required to do [[+files]] validation when submitting a form. Verification: the number of attached images is at least 3. The form should not be sent without attached files.
The problem is that [[+ files]] is not a field. This is the snippet output. How do I check?

Could you explain why you need to validate something that is not an input, and tell us more about what kind of validation you need?

It seems that with the TicketForm in Tickets you can use the validation functionality from FormIt (if you have the extra FormIt installed).

So you can write a custom validator like you would with FormIt and then add the properties &customValidators and &validate to your TicketForm-call:

[[!TicketForm? &customValidators=`imageCountValidator` &validate=`tid:imageCountValidator`]]

For your custom validator create a snippet with the name imageCountValidator and code like this:

<?php
$tid = (int)$value;

//Query the amount of images in the database table modx_tickets_files
$q = $modx->newQuery('TicketFile');
$q->where(array('class' => 'Ticket'));
$q->andCondition(array('parent' => $tid, 'deleted' => 0, 'createdby' => $modx->user->id), null, 1);
$img_count = $modx->getCount('TicketFile', $q);

if ($img_count < 3) {
    //Less than 3 images found
    $validator->addError($key,'Not enough images!');
    return false;
}
return true;

When you select a file in the form, a AJAX-request is executed and the file information is stored in the database table modx_tickets_files. So when you send the form you can check this database table to determine the number of images.

The form does not leave if the number of images is less than 3. But the toast notification ‘Not enough images!’. Inside the form is written
What could be the problem? Logs are empty

Isn’t that what you want? That the form is not sent without 3 attached files and that an error message is shown to indicate the reason why.

1 Like

The check works. Notice is not displayed. Not with jGrowl. Not the usual sniffing at the bottom of the field.

How to call a jQuery.jGrowl message, if the snippet determines that the number of images is less than 3?

$tid = (int)$value;
$q = $modx->newQuery('TicketFile');
$q->where(array('class' => 'Ticket'));
$q->andCondition(array('parent' => $tid, 'deleted' => 0, 'createdby' => $modx->user->id), null, 1);
$img_count = $modx->getCount('TicketFile', $q);
if ($img_count < 3) {
    //Less than 3 images found
    $errorMsg = "jQuery.jGrowl('You must submit at least 3 photos!')";
    $validator->addError($key, $errorMsg);
    return false;
}
return true;

not working

You can slightly improve the displaying of the error message by making these changes:

  • Add a span with id="files-error" to your form template:
...
<div class="ticket-form-files">
	[[+files]]
	<span class="error" id="files-error"></span>
</div>
...
  • Change the property &validate in the call to TicketForm to files:imageCountValidator:
[[!TicketForm? &customValidators=`imageCountValidator` &validate=`files:imageCountValidator`]]
  • Replace the first line in the snippet imageCountValidator with the following line:
$tid = (int)$_POST['tid']; //replaces the line $tid = (int)$value;

As far as I can tell you can’t display a jGrowl message without changing the code. The problem is that the json with the error message that is returned has an empty message field

{
	"success": false,
	"message": "", //this part is displayed with jGrowl
	"data": {
		"tid": {
			"field": "tid",
			"message": "Not enough images!"
		}
	}
}

If you really want to show a jGrowl message, you probably have to change the code. Either here in PHP where the return message is generated or here in JS where the message is shown.

Thank you very much. Everything worked)