Validate select2 in yii2 - jquery-select2

I have a textInput in _form.php. Then, I change it become select2. But after I change it, the validation is not working. What's the problem? How can I make a validation in select2 so that it cannot be blank?
This is the code:
_form.php
<?php
$formatJs = <<< 'JS'
var formatPenerima = function (penerima) {
if (penerima.loading) {
return penerima.text;
}
var markup =
'<div class="row">' +
'<div class="col-sm-4">' +
'<b style="margin-left:5px">' + penerima.text + '</b>' +
'</div>' +
'<div class="col-sm-3"><i class="fa fa-phone"></i> ' + penerima.telepon + '</div>' +
'<div class="col-sm-4"><i class="fa fa-envelope"></i> ' + penerima.mail + '</div>' +
'</div>';
return '<div style="overflow:hidden;">' + markup + '</div>';
};
var formatPenerimaSelection = function (penerima) {
return penerima.id || penerima.text;
}
JS;
// Register the formatting script
$this->registerJs($formatJs, \yii\web\View::POS_HEAD);
// Script to parse the results into the format expected by Select2
$resultsJs = <<< JS
function (data, params) {
params.page = params.page || 1;
return {
results: data.results, // check here
/*pagination: {
more: (params.page * 30) < data.total_count
}*/
};
}
JS;
$url = Url::to(['/paket/jsonlist']);
// Render your widget
// Get data from dummy data
echo $form->field($model, 'no_induk')->widget(Select2::className(), [
'name' => 'kv-repo-template',
'value' => '',
'initValueText' => '',
'options' => ['placeholder' => 'Cari pemilik ...', 'id' => 'pengambil'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'ajax' => [
'url' => $url,
'dataType' => 'json',
'delay' => 250,
'data' => new JsExpression('function(params) { return {q:params.term, page: params.page}; }'),
'processResults' => new JsExpression($resultsJs),
'cache' => true
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('formatPenerima'),
'templateSelection' => new JsExpression('formatPenerimaSelection'),
],
])->label('Pemilik');
?>
and this is my model rules:
public function rules()
{
return [
[['no_induk', 'nama', 'no_telepon', 'email', 'kategori_paket', 'nama_pengirim'/*, 'tanggal_sampai'*/],
'required', 'message' => '{attribute} tidak boleh kosong.'],
[['id_satpam_pengentry'], 'required', 'message' => 'Nama satpam tidak boleh kosong.'],
[['kategori_paket', 'status', 'id_satpam_pengentry', 'id_satpam_penyetuju'], 'integer'],
[['tanggal_sampai', 'tanggal_pengambilan'], 'safe'],
[['no_induk', 'email'], 'string', 'max' => 255],
[['nama', 'nama_pengirim', 'nama_pengambil'], 'string', 'max' => 128],
[['no_telepon'], 'string', 'max' => 64]
];
}

you can set "required = true" in the "options" array like this
'options' => ['placeholder' => 'Cari pemilik ...', 'class' => 'form-control', 'required' => true],

you have to put
class => "form-control" in your options and remove id, so validation will work

echo $form->field($model, 'no_induk')->widget(Select2::className(), [
'name' => 'kv-repo-template',
'value' => '',
'initValueText' => '',
'options' => ['placeholder' => 'Cari pemilik ...', 'class' => 'form-control'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'ajax' => [
'url' => $url,
'dataType' => 'json',
'delay' => 250,
'data' => new JsExpression('function(params) { return {q:params.term, page: params.page}; }'),
'processResults' => new JsExpression($resultsJs),
'cache' => true
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('formatPenerima'),
'templateSelection' => new JsExpression('formatPenerimaSelection'),
],
])->label('Pemilik');

Related

When Im Trying to Sort the DataGrid ..Data Was Disappearing ..But Data Was Coming As Json Response and it was not Showing on UI with Sortable()

Data Was Binding When Sortable() was clicked data was Disappearing on UI
#(Html.Kendo().Grid<Keys>(Model.baseKeysLocations).Name("SearchResultsGridLocation")
//.Sortable()
.Sortable(Sortable => Sortable.AllowUnsort(false))
.HtmlAttributes(new { style = "height: 450px" })
.Resizable(r => r.Columns(true))
.Reorderable(r => r.Columns(true))
.Scrollable(s => s.Virtual(true))
.Editable(e => e.Mode(GridEditMode.InCell))
.Pageable(p => p.Numeric(false).PreviousNext(false).Messages(m => m.Display("Total: {2}")))
.DataSource(ds => ds
.Ajax()
.AutoSync(true)
.Read(read => read.Action("Grid_KeyLocationRead", "Keys", new { #schdate = "", #drv = "" }))
.Model(m =>
{
m.Id(f => f.UniqueId);
m.Field(f => f.Schedule);
m.Field(f => f.TableId).Editable(false);
m.Field(f => f.FobId).Editable(false);
m.Field(f => f.RoomKey).Editable(false);
m.Field(f => f.Community).Editable(false);
m.Field(f => f.Lease).Editable(false);
m.Field(f => f.RoomKey).Editable(false);
m.Field(f => f.Driver).Editable(false);
m.Field(f => f.Status).Editable(false);
m.Field(f => f.FobId);
}
)
)
.Columns(columns =>
{
columns.Bound(f => f.UniqueId).Width("8rem").Hidden();
columns.Bound(f => f.TableId).Title("Id").Width("5rem").Hidden();
columns.Bound(f => f.RoomKey).Title("Key Location").Width("6rem");
columns.Bound(f => f.Community).Title("Community").Width("6rem");
columns.Bound(f => f.Lease).Title("Master").Width("6rem");
columns.Bound(f => f.Driver).Title("Driver").Width("6rem");
columns.Bound(client => client.Status).ClientTemplate("# if (Status == true) { #" + "IN" + "# } else {#" + "OUT" + "# } #").Title("Status").Width("8rem");
})
.Sortable()
)
</div>
*Data Was Binding When Sortable() was clicked data was Disappearing on UI*
*Data Was Binding *1: https://i.stack.imgur.com/qRAmu.png
When Pressing Sort Function Data Is Disappearing[2]: https://i.stack.imgur.com/LVSld.png
Trying to Sort the DataGrid ..Data Was Disappearing ..But Data Was Coming As Json Response and it was not Showing on UI with Sortable() *
function SearchLocationResults(search) {
$filter = new Array();
var leaseuid = null, complexuid = null;
if (search == true) {
if ($("#baseLocationViewModel_ComplexUId").data("kendoDropDownList").value() != '' && $("#baseLocationViewModel_ComplexUId").data("kendoDropDownList").value() != null && $("#baseLocationViewModel_ComplexUId").data("kendoDropDownList").value() != undefined) {
$filter.push({ field: "Driver", operator: "isequalto", value: $("#baseLocationViewModel_DriverUId").data("kendoDropDownList").value() });
complexuid = $("#baseLocationViewModel_ComplexUId").data("kendoDropDownList").value();
}
if ($("#baseLocationViewModel_MasterUId").data("kendoDropDownList").value() != '' && $("#baseLocationViewModel_MasterUId").data("kendoDropDownList").value() != null && $("#baseLocationViewModel_MasterUId").data("kendoDropDownList").value() != undefined) {
$filter.push({ field: "LeaseUId", operator: "isequalto", value: $("#baseLocationViewModel_MasterUId").data("kendoDropDownList").value() });
leaseuid = $("#baseLocationViewModel_MasterUId").data("kendoDropDownList").value();
}
}
$(".loadermodel").removeClass('d-none');
$.ajax({
url: '/Keys/Keys/Grid_KeyLocationRead',
type: "POST",
dataType: "json",
contentType: 'application/json; charset=utf-8',
async: false,
data: JSON.stringify({
request: $filter, schedule: $("#baseLocationViewModel_Schedule").val(), driver: $("#baseLocationViewModel_DriverUId").data("kendoDropDownList").value(), _complexUId: complexuid, _leaseUId: leaseuid
}),
cache: false,
success: function (result) {
$("#SearchResultsGridLocation").data('kendoGrid').dataSource.data([]);
$("#SearchResultsGridLocation").data('kendoGrid').dataSource.data(result);
$(".loadermodel").addClass('d-none');
},
error: function (err) {
$(".loadermodel").addClass('d-none');
}
});
}

How to get the selected option of a radion button element in Zend Framework 2?

In a Fieldset I have an Element\Radio foo and Element\Text bar.
public function init()
{
$this->add(
[
'type' => 'radio',
'name' => 'foo',
'options' => [
'label' => _('foo'),
'value_options' => [
[
'value' => 'a',
'label' => 'a',
'selected' => true
],
[
'value' => 'b',
'label' => 'b'
]
]
]
...
]);
$this->add(
[
'name' => 'bar',
'type' => 'text',
'options' => [
'label' => 'bar',
...
],
...
]);
}
The validation of the field bar is depending on the selected foo option. It's easy to implement, if I can get the selected value of foo:
public function getInputFilterSpecification()
{
return [
'bar' => [
'required' => $this->get('foo')->getCheckedValue() === 'a',
...
],
];
}
But there is no method Radio#getCheckedValue(). Well, I can iterate over the $this->get('foo')->getOptions()['value_options'], but is it really the only way?
How to get (in the Fieldset#getInputFilterSpecification()) the selected option of a Zend\Form\Element\Radio?
The selected option gets POSTed to the server along with everything else from the HTML form and is all of this is available in validators through the $context array.
You can create a conditionally required field by using a callback validator and the $context array like this:
public function getInputFilterSpecification() {
return [
'bar' => [
'required' => false,
'allow_empty' => true,
'continue_if_empty' => true,
'required' => true,
'validators' => [
[
'name' => 'Callback',
'options' => [
'callback' => function ($value, $context) {
return $context['foo'] === 'a'
},
'messages' => [
\Zend\Validator\Callback::INVALID_VALUE => 'This value is required when selecting "a".'
]
]
]
]
],
];
}
That would check if 'foo' is equal to 'a', i.e. option 'a' is selected and return true when it is, which marks the input as valid, and false when it's not, marking the input invalid.

Yii2 - input search with auto-complete

I am using default Yii2 library for auto-complete. How can I make it, so it is reading values from DB while user is typing?
This is code I have so far, but query is done when the page is created:
echo AutoComplete::widget([
'name' => 'tradeName',
'model' => TradeNames::find()->select('name')->all(),
'options' => [
'class' => 'form-control'
],
'clientOptions' => [
'source' => array_column(TradeNames::find()->select('name')->asArray()->all(), 'name'),
},
],
]);
I followed this advice
jqueryui.com/autocomplete/#multiple and have written next code
<div id="autocomplete" class="ui-widget">
<?= \yii\jui\AutoComplete::widget([
'attribute' => 'attribute',
'name' => 'tradeName',
'clientOptions' => [
'source' => \Yii::$container->get('JsExpression',['function(request, response) {
response( $.ui.autocomplete.filter( window.dataAsArray, extractLast( request.term ) ) );
}']),
'select' => \Yii::$container->get('JsExpression',['function(event, ui) {
var terms = split( this.value );
terms.pop();
terms.push( ui.item.value );
terms.push( "" );
this.value = terms.join( ", " );
return false;
}']),
'focus' => \Yii::$container->get('JsExpression',['function() {
return false;
}']),
]
]) ?>
</div>
<script>
window.dataAsArray = ['item1', 'item2', 'item3'];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$(document).ready( function() {
$('#autocomplete').on('keydown', function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB && $( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
});
});
</script>
maybe it help to someone
try this
use yii\jui\AutoComplete;
use yii\web\JsExpression;
<?php
$data = TradeNames::find()
->select(['name as value', 'name as label','id as id'])
->asArray()
->all();
echo 'Trade Names' .'<br>';
echo AutoComplete::widget([
'name' => 'tradeName',
'id' => 'trade_name',
'clientOptions' => [
'source' => $data,
// 'minLength'=>'3',
'autoFill'=>true,
'select' => new JsExpression("function( event, ui ) {
$('#memberssearch-family_name_id').val(ui.item.id);//#memberssearch-family_name_id is the id of hiddenInput.
}")],
]);
?>
<?= Html::activeHiddenInput($model, 'tradeName')?>

How to validate if 'email' exists Zend Framework 2

I want to use NoRocordExists to validate if email exists before insert the information inside the mysql DB but i don't get how can i call $dbapater.
This is my code of my inputfilter class
$norecord_exists = new NoRecordExists(
array(
'table' => 'users',
'field' => 'email',
'adapter' => $dbadapter
)
);
$norecord_exists->setMessage('Email already exists !', 'recordFound');
$this->add(array(
'name' => 'email',
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
$norecord_exists,
array(
'name'=>'EmailAddress',
'options'=> array(
'allowWhiteSpace'=>true,
'messages' => array(
\Zend\Validator\EmailAddress::INVALID_HOSTNAME=>'Email incorrecto',
),
),
),
)
));
With ZF2, I advise you to use FactoryInterface like this :
UserFormFactory.php
<?php
namespace User\Form\Service;
use User\Form\UserForm;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class UserFormFactory implements FactoryInterface
{
/**
* #param ServiceLocatorInterface $serviceLocator
* #return UserForm
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
/* #var ServiceLocatorInterface $sl */
$sl = $serviceLocator->getServiceLocator();
$form = new UserForm();
$form->setDbAdapter($sl->get('Zend\Db\Adapter\Adapter'));
return $form;
}
}
UserForm.php
<?php
namespace User\Form;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;
class UserForm extends Form implements InputFilterProviderInterface
{
/**
* #var AdapterInterface
*/
protected $dbAdapter;
/**
* Initialisation
*/
public function init()
{
$this->add([
'name' => 'email',
'type' => 'Email',
'options' => [
'label' => 'Email',
],
'attributes' => [
'class' => 'form-control',
'required' => 'required',
],
]);
// ...
$this->add([
'name' => 'submit',
'type' => 'Submit',
'attributes' => [
'value' => 'Connexion',
'class' => 'btn btn-default',
],
]);
}
/**
* InputFilter
*
* #return array
*/
public function getInputFilterSpecification()
{
return [
'email' => [
'required' => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
['name' => 'StringToLower'],
],
'validators' => [
[
'name' => 'EmailAddress',
], [
'name' => 'Db\NoRecordExists',
'options' => [
'table' => 'user',
'field' => 'email',
'adapter' => $this->getDbAdapter(),
],
],
],
],
// ...
];
}
/**
* #return AdapterInterface
*/
public function getDbAdapter()
{
return $this->dbAdapter;
}
/**
* #param AdapterInterface $dbAdapter
* #return UserForm
*/
public function setDbAdapter(AdapterInterface $dbAdapter)
{
$this->dbAdapter = $dbAdapter;
return $this;
}
}
module.config.php
return [
'form_elements' => [
'factories' => [
'UserForm' => 'User\Form\Service\UserFormFactory',
],
],
];
Finally, in your controller
$form = $this->getServiceLocator('FormElementManager')->get('UserForm');
//..
if ($form->isValid()) // ...
You need to move this code
$norecord_exists = new NoRecordExists(
array(
'table' => 'users',
'field' => 'email',
'adapter' => $dbadapter
)
);
$norecord_exists->isValid(EMAIL_FROM_THE_FORM_FIELD) {
return false; //email exists
}
return true; // email doen't exists
in your Controller or in a separate service/factory. $dbadapter usually holds the instance to your Zend\Db\Adaptr\Adapter or any other configuration you have.

How to validate empty input in Zend Framework 2

I'm doing a registration form in ZF2, but I don't get how to validate. Validation seems not working.
I'm adding the validators array, but it doesn't work anyways. I don't know how can I fix that.
This is my code of controller:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Form\Formularios;
use Zend\Db\Adapter\Adapter;
use Application\Modelo\Entity\Usuarios;
class FormularioController extends AbstractActionController
{
public $dbAdapter;
public function indexAction()
{
return new ViewModel();
}
public function registroAction()
{
if($this->getRequest()->isPost())
{
$this->dbAdapter=$this->getServiceLocator()->get('Zend\Db\Adapter');
$u=new Usuarios($this->dbAdapter);
//echo "se recibiĆ³ el post";exit;
$data = $this->request->getPost();
$u->addUsuario($data);
return $this->redirect()->toUrl($this->getRequest()->getBaseUrl().'/application/formulario/registro/1');
}else
{
//zona del formulario
$form=new Formularios("form");
$id = (int) $this->params()->fromRoute('id', 0);
$valores=array
(
"titulo"=>"Registro de Usuario",
"form"=>$form,
'url'=>$this->getRequest()->getBaseUrl(),
'id'=>$id
);
return new ViewModel($valores);
}
}
}
this is my form code with validator
class Formularios extends Form
{
public function __construct($name = null)
{
parent::__construct($name);
$this->add(array(
'name' => 'name',
'required' => true,
'allow_empty' => false,
'options' => array(
'label' => 'Nombre Completo',
),
'attributes' => array(
'type' => 'text',
'class' => 'input'
),
'filters' => [ ['name' => 'StringTrim'], ],
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'Ingrese Nombres.',
))))
));
$this->add(array(
'name' => 'lastname',
'required' => true,
'options' => array(
'label' => 'Apellido',
),
'attributes' => array(
'type' => 'text',
'class' => 'input'
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'Ingrese Apellidos.',
))))
));
Thanks in advance
First problem.
$data = $this->request->getPost(); should be $data = $this->getRequest()->getPost();
Second problem is that you call your validators direclty when you build your form in the view, which is wrong. The right way to do is via an inputFilter. Now, there are many ways to to this, for example: with or without a factory called from your model or via the for class with a form element manager
I will show you the model way with a factory since it's easier for new comers.
namespace MyModule\Model;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class MyModel implements InputFilterAwareInterface
{
/**
* #var null $_inputFilter inputFilter
*/
private $_inputFilter = null;
// some more code like exhnageArray get/set method
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add(
$factory->createInput([
'name' => 'id',
'required' => false,
'filters' => [
['name' => 'Int'],
],
])
);
$inputFilter->add(
$factory->createInput([
"name"=>"title",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 200,
],
],
],
])
);
$inputFilter->add(
$factory->createInput([
"name"=>"text",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
],
],
],
])
);
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
Third proble. DO NOT EVER use serviceManager in controller. It's a really really really bad practice. Instead use a factory.

Resources