how to automatically enter data from form one to another form yii2 - yii

I have a MySQL table and model resume which contains fields
'resume_id', 'lao', 'persen', 'eom', 'tgt_perpetugas' and 'tgt_pergeseran'
I also have another table/model resumes which also contains
'resumes_id', 'lao', 'persen', 'eom', 'tgt_perpetugas' and 'tgt_pergeseran'
Suppose the resume table is already filled with
'resume_id', 'lao', 'persen', 'eom', 'tgt_perpetugas','tgt_pergeseran'
When I am entering data in resumes form, when I select the 'lao' via drop-down field related to resume table, I want the related
'persen', 'eom', 'tgt_perpetugas' and 'tgt_pergeseran'
fields to be auto-filled. my reference but 'Error in ajax request'. how to automatically enter data from form one to another form yii2
how to fix the error or is there a recommendation?
My _form.php for 'resumes' looks like this
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use app\models\Resume;
$routeAjax = \yii\helpers\Url::toRoute("resume/resumes");
$js=<<<JS
function getRelatedFields(lao_id){
$.ajax({
url: '$routeAjax',
dataType: 'json',
method: 'GET',
data: {id: lao_id},
success: function (data, textStatus, jqXHR) {
$('#resumes-persen').val(data.persen);
$('#resumes-eom').val(data.eom);
$('#resumes-tgt_perpetugas').val(data.tgt_perpetugas);
$('#resumes-tgt_pergeseran').val(data.tgt_pergeseran);
},
beforeSend: function (xhr) {
alert('loading!');
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('An error occured!');
alert('Error in ajax request'+textStatus'\n'+errorThrown);
}
});
}
JS;
$this->registerJs($js, \yii\web\View::POS_READY);
?>
<div class="resumes-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'lao')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Resume::find()->all(),'lao','lao'),
'language' => 'en',
'options' => ['placeholder' => 'Pilih LAO'],
'pluginOptions' => [
'allowClear' => true
],
'pluginEvents'=>[
'select2:select' => 'function(e){getRelatedFields(e.params.data.id);}',
]
]); ?>
<?= $form->field($model, 'persen')->textInput(['type' => 'number','maxlength' => true, 'readOnly'=>false])->label('Perpetugas %') ?>
<?= $form->field($model, 'eom')->textInput(['maxlength' => true])->label('EOM') ?>
<?= $form->field($model, 'tgt_perpetugas')->textInput(['maxlength' => true, 'readOnly'=>true])->label('Target Perpetugas') ?>
<?= $form->field($model, 'tgt_pergeseran')->textInput(['maxlength' => true, 'readOnly'=>true])->label('Target Pergeseran') ?>
<center>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</center>
<?php ActiveForm::end(); ?>
</div>
And in the ResumesController,I have added. this:
public function actionResumes($id){
// you may need to check whether the entered ID is valid or not
$model = \app\models\Resume::findOne(['lao'=>$id]);
return \yii\helpers\Json::encode([
'eom'=>$model->eom,
'persen'=>$model->persen,
'tgt_pergeseran'=>$model->tgt_pergeseran,
'tgt_perpetugas'=>$model->tgt_perpetugas
]);
}

What I understand is that you want the fields
'persen', 'eom', 'tgt_perpetugas', 'tgt_pergeseran'
against the lao saved in the Resume model matching the dropdown() in the Resumes form lao field.
If that is correct then first you need to use the Select2 event select2:selectrather than using the traditional onchange event. Make a few changes to your Select2 and the script on top of the view.
Replace your select2 with the following
<?= $form->field($model, 'lao')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Lao::find()->all(),'lao_id','lao_id'),
'language' => 'en',
'options' => ['placeholder' => 'Pilih LAO'],
'pluginOptions' => [
'allowClear' => true
],
'pluginEvents'=>[
'select2:select' => 'function(e){getRelatedFields(e.params.data.id);}',
]
]); ?>
Replace the script on top of the view with the following
$routeAjax = \yii\helpers\Url::toRoute("resume/resumes");
$js=<<<JS
function getRelatedFields(lao_id){
$.ajax({
url: '$routeAjax',
dataType: 'json',
method: 'GET',
data: {id: lao_id},
success: function (data, textStatus, jqXHR) {
$('#resumes-persen').val(data.persen);
$('#resumes-eom').val(data.eom);
$('#resumes-tgt_perpetugas').val(data.tgt_perpetugas);
$('#resumes-tgt_pergeseran').val(data.tgt_pergeseran);
},
beforeSend: function (xhr) {
alert('loading!');
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('An error occured!');
alert('Error in ajax request'+textStatus'\n'+errorThrown);
}
});
}
JS;
$this->registerJs($js, \yii\web\View::POS_READY);
Then you want to populate the similar fields from the Resume model to the Resumes ActiveForm when you select any option in the lao dropdown. You should be fetching the lao in the Resume model not id in the Resumes model.
So replace your action with the below
public function actionResumes($id)
{
// you may need to check whether the entered ID is valid or not
$model = \app\models\Resume::findOne(['lao' => $id]);
return \yii\helpers\Json::encode([
'eom' => $model->eom,
'persen' => $model->persen,
'tgt_pergeseran' => $model->tgt_pergeseran,
'tgt_perpetugas' => $model->tgt_perpetugas
]);
}

Related

Yii2 Pjax and GridView - refresh is not working properly

I am using the Pjax and GridView, and trying to make it work properly after the status of the item is changed. Currently, after the action is over, and server sends back the result, the whole GridView will be replaced with the text (response from the controller).
The Pjax code:
<?php
Pjax::begin(['id' => 'product-manage']);
echo GridView::widget([
'dataProvider' => $productsProvider,
'filterModel' => $filterModel,
'filterPosition' => 'header',
'columns' => [
['class' => 'yii\grid\SerialColumn'],
....
['class' => 'yii\grid\ActionColumn',
'header' => 'Actions',
'buttons' => [
....
'toggle-publish' => function ($url, $model) {
$html = $model->published ? '<span class="glyphicon glyphicon-remove"></span>' : '<span class="glyphicon glyphicon-ok"></span>';
return Html::a($html, $url, [
'title' => $model->published ? 'Unpublish' : 'Publish',
'data-pjax' => 'product-manage',
'data' => [
'confirm' => $model->published ? 'Are you sure you want to unpublish ' . $model->inci . ' ?' : 'Are you sure you want to publish ' . $model->inci . ' ?',
'method' => 'post',
],
]);
},
],
'template' => '<span class="block text-center">{view}</span>
<span class="block text-center">{update}</span>
<span class="block text-center">{toggle-default-product}</span>
<span class="block text-center">{toggle-publish}</span>'
],
],
]);
Pjax::end();
?>
Controller:
$response = Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_JSON;
$response->statusCode = 200;
$response->data = Yii::$app->controller->renderPartial('/partials/_alerts', [
'message' => $message,
'type' => 'success'
]);
return $response;
What am I doing wrong here?

yii2 form input ajax validation will not perfom

im trying to active ajax validation in my form according the docs i added(
'enableAjaxValidation' => true and validationUrl )with its action
can anyone tell me why validation will not perform on my form ?
i dont have any error in console
thankyou
this is my controller
public function actionCreate()
{
$model = new Developers();
return $this->render('_form', [
'model' => $model
]);
}
public function actionValidation(){
$model = new Developers();
if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()) )
{
Yii::$app->response->format = 'json';
return ActiveForm::validate($model);
}
}
and its my form
<div class="developer-form">
<?php $form = ActiveForm::begin([
'id' => $model->formName(),
'enableAjaxValidation' => true,
'validationUrl'=>\yii\helpers\Url::toRoute('site-admin/validation')
]); ?>
<?= $form->field($model, 'name')->textInput(['minlength'=>true]) ?>
<?= $form->field($model, 'family')->textInput() ?>
<?= $form->field($model, 'phone')->textInput() ?>
<?= $form->field($model, 'email')->textInput() ?>
<?= $form->field($model, 'address')->textInput() ?>
<?= $form->field($model, 'brithday')->textInput() ?>
<?= $form->field($model, 'age')->textInput() ?>
<?= $form->field($model, 'ability')->textInput() ?>
<?= $form->field($model, 'role')->textInput() ?>
<?= $form->field($model, 'point')->textInput() ?>
<?= $form->field($model, 'join_date')->textInput() ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
and here my model rules function
public function rules()
{
return [
[['name',
'family',
'phone',
'email',
'address',
'brithday',
'age',
'ability',
'role',
'point',
'join_date',
], 'required'],
[['id'], 'integer'],
[['date_project_done','estimate_for_next_project','number_of_project','activity_rate','free_rate','project_done'], 'safe'],
[['address'], 'string', 'max' => 100],
[['name'], 'string', 'min' => 3],
];
}
Use below code in view file form variable :
<?php $form = ActiveForm::begin([
'id' => 'login-form', //your form id
'enableAjaxValidation' => true,
'enableClientValidation' => false,
'validateOnBlur' => false,
'validateOnType' => false,
'validateOnChange' => false,
]) ?>
Use below code in your controllers action :
public function actionCreate()
{
$model = new Developers();
if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()) )
{
if($model->validate())
{
// do here anything
$model->save();
}
else
{
Yii::$app->response->format = 'json';
return ActiveForm::validate($model);
}
}
else
{
return $this->render('_form', [
'model' => $model
]);
}
}

click yii2 gridview linkpager's page no, jump error

the gridview if on right of the page,left is some menus,when click on page no 2,it dose not only refresh the gridview,but all page including left part are lost——a totally new page come out!help~
there is the debugging Screenshot:
my action is
public function actionList()
{
$model = new Loan();
$dataProvider = new ActiveDataProvider([
'query' => $model->find(),
'pagination' => [
'pagesize' => '1',
],
]);
return $this->renderPartial('list', ['model' => $model, 'dataProvider' => $dataProvider]);
}
my view is:
<?php
use yii\grid\GridView;
use yii\grid\SerialColumn;
use yii\helpers\Html;
use yii\helpers\Url;
use yii\widgets\LinkPager;
?>
<?=GridView::widget([
'dataProvider' => $dataProvider,
'layout'=> '{items}{pager}',
'columns' => [
['attribute' =>'loan_type','label'=>'借款类型','options' => ['width' => '80']],
['attribute' =>'amount','label'=>'金额','options' => ['width' => '80']],
['attribute' =>'rate','label'=>'还款利率','options' => ['width' => '80']],
['attribute' =>'fee','label'=>'手续费','options' => ['width' => '80']],
['attribute' =>'status','label'=>'状态','options' => ['width' => '80'] ],
['attribute' =>'comment','label'=>'审核意见','options' => ['width' => '80']],
['attribute' => 'created_at','value' =>function($model){return date('Y-m-d',strtotime($model->created_at));},'label'=>'申请时间','options' => ['width' => '150']],
[
'class' => 'yii\grid\ActionColumn',
'header' => '操作',
'template' => '{audit}',
'buttons' => [
'audit' => function ($url,$model) {
return Html::a('<span id="xxxx" class="glyphicon glyphicon-user"></span>','#',['title'=>'审核',
'onclick'=>"
$.ajax({
type: 'GET',
dataType: 'text',
url: 'http://182.92.4.87:8000/index.php?r=loan/pj', //目标地址
error: function (XMLHttpRequest, textStatus, errorThrown) {alert(XMLHttpRequest.status + ':' + XMLHttpRequest.statusText); },
success: function (page)
{
$('.ucRight').html(page);
}
});
return false;",
]);},
],
'urlCreator' => function ($action, $model, $key, $index) {
return Yii::$app->getUrlManager()->createUrl(['loan/list','id' => $model->status]);
},
'headerOptions' => ['width' => '80'],
],
],
]);
?>
The reason for your problem is that you haven't prevented the html link from directing to a new page, so your user is clicking on the link, which then loads a new page with the contents returned by the server; in this case a page of information with no layout applied. You need to add event.preventDefault() before the ajax call to stop this behaviour.
However, as #arogachev said, if you simply want to use pagination without a page refresh, then just use pjax. That is what pjax is designed for,

Yii2 Invalid CAPTCHA action ID in module

I am getting the Invalid CAPTCHA action ID Exception in my custom contactus module. I managed to display the captcha but models validation rule throws the invalid action ID exception. Below is my code:
contactus/controllers/DefaultController.php
class DefaultController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::className(),
'rules' => [
[
'actions' => ['captcha','index'],
'allow' => true,
],
]
]
];
}
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
public function actionIndex()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post()) && $model->contact(setting::ADMIN_EMAIL_ADDRESS)) {
Yii::$app->session->setFlash('contactFormSubmitted');
return $this->refresh();
} else {
return $this->render('index', [
'model' => $model,
]);
}
}
}
contactus/models/ContactForm.php
public function rules()
{
return [
// name, email, subject and body are required
[['name', 'email', 'subject', 'body','verifyCode'], 'required'],
// email has to be a valid email address
['email', 'email'],
// verifyCode needs to be entered correctly
['verifyCode', 'captcha','captchaAction'=>'default/captcha'],
];
}
contactus/views/default/index.php
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($model, 'subject') ?>
<?= $form->field($model, 'body')->textArea(['rows' => 6]) ?>
<?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [
'captchaAction' => 'default/captcha',
'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
]) ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
</div>
<?php ActiveForm::end(); ?>
I get the below error:
Exception (Invalid Configuration) 'yii\base\InvalidConfigException' with message 'Invalid CAPTCHA action ID: default/captcha'in E:\wamp\www\yii-application\vendor\yiisoft\yii2\captcha\CaptchaValidator.php:81
Am I missing something?
You should modify your validation rule :
['verifyCode', 'captcha','captchaAction'=>'/contactus/default/captcha'],

Why captcha reload not work when I am adding the CSRF in ZEND?

When I am adding the below code the reload captcha work fine
In ZEND FORM:
$this->setName("login");
$this->setMethod('post');
$this->addElement('text', 'username', array(
'filters' => array('StringTrim', 'StringToLower'),
'validators' => array(
array('StringLength', false, array(0, 50)),
),
'required' => true,
'label' => 'Username:',
));
$this->addElement('password', 'password', array(
'filters' => array('StringTrim'),
'validators' => array(
array('StringLength', false, array(0, 50)),
),
'required' => true,
'label' => 'Password:',
));
// Add a captcha
$this->addElement('captcha', 'captcha', array(
'label' => 'Please enter the 5 letters displayed below:',
'required' => true,
'captcha' => array(
'captcha' => 'Figlet',
'wordLen' => 5,
'timeout' => 300
)
));
$captcha = $this->createElement('captcha', 'captcha', array(
'required' => true,
'captcha' => array(
'captcha' => 'Image',
'font' => APPLICATION_PATH . '/../public/fonts/arial.ttf',
'fontSize' => '24',
'wordLen' => 5,
'height' => '50',
'width' => '150',
'imgDir' => APPLICATION_PATH.'/../public/captcha',
'imgUrl' => Zend_Controller_Front::getInstance()->getBaseUrl().'/captcha',
'dotNoiseLevel' => 50,
'lineNoiseLevel' => 5,
),
'description' => 'Refresh Captcha Image'
));
$captcha->setLabel('Please type the words shown:');
$captcha->removeDecorator("htmlTag")->removeDecorator('label');
$captcha->addDecorator('Errors', array('class' => 'err-username', 'style' => 'display:none'));
$captcha->addDecorator('Description', array('id' => 'refreshcaptcha'));
$this->addElement($captcha);
$this->getElement('captcha')->removeDecorator("htmlTag")->removeDecorator('label');
// And finally add some CSRF protection
/*$this->addElement('hash', 'csrf', array(
'ignore' => true,
));*/
$this->addElement('submit', 'login', array(
'required' => false,
'ignore' => true,
'label' => 'Login',
));
In phtml:
<script type="text/javascript">
$(document).ready(function() {
$('#refreshcaptcha').click(function() {
$.ajax({
url: "<?php echo $this->url(array('controller' => 'auth', 'action' => 'refresh'), 'default', false) ?>",
dataType:'json',
success: function(data) {
$('#contactForm img').attr('src', data.src);
$('#captcha-id').attr('value', data.id);
}
});
});
});
</script>
<?php
//Default
//$this->form->setAction($this->url());
//echo $this->form;
?>
<?php
$errorsMessages = $this->form->getMessages();
//http://www.websitefactors.co.uk/zend-framework/2011/06/error-class-on-form-field-errors-using-zend-form/
?>
<?php
foreach($this->form->getMessages() as $elemName=>$messages) {
foreach($messages as $message) {
$label = $this->form->getElement($elemName)->getLabel();
echo $this->escape($label.' '.$message)."<br>" ;
}
}
?>
<div id="contactForm">
<form method="<?php echo $this->form->getMethod(); ?>" action="<?php echo $this->form->getAction(); ?>">
<?php echo $this->form->username->renderViewHelper(); ?>
<?php echo $this->form->password->renderViewHelper(); ?>
<?php echo $this->form->captcha; ?>
<?php //echo $this->form->csrf->renderViewHelper(); ?>
<?php echo $this->formSubmit('submit', 'Sign in',array('class'=>'button')); ?>
</form>
</div>
When I click the "Refresh Captcha Image", the captcha image is replaced without refreshing the page and it works fine, but when I add the below CSRF (cross site request forgery) code and reload the captcha code and then submit, login is never successful. It gives me the error: "Value is required and can't be empty" or "Please type the words shown: Captcha value is wrong"
$this->addElement('hash', 'csrf', array(
'ignore' => true,
));
Zend_Form_Element_Hash gets generated on every request. So what is happening is when you click "Refresh Captcha Image" a new request is generated. Then, when you submit your form, you've already used up your request so the csrf check fails since the tokens are out of sync.
To fix this you could do the wrong thing and just increase your hop count to some high number. This will help to negate the security you're after, though. One way to correctly fix this is to re-initialize the token in your auth controller in the refresh() action. You can then send back a json_encoded response that contains this new token.
....
$form->captcha->initCsrfToken(); //recreate token and send it back
$responseArray['hash'] = $form->captcha->getValue();
echo Zend_Json::encode($responseArray);
After you do the ajax call, you can then replace the token with what you get back from your refresh() action. Example:
var newHash = jQuery.parseJSON(data).hash;
$('#yourcsrfelement').val(newHash);