Insert without refresh in yii2 - javascript

i am developing a web application using yii2 .i did a thumbs up and thumbs down buttons. it just insert the user and what the person choose up /down into a table . but i don't think i am going about it the right way because after the user clicks up or down it refreshes. i want it to insert without refreshing.
this is the view
<?php $form = ActiveForm::begin(['id' => "contact-form",
'enableClientValidation' => false,
]);
?>
<input type="hidden" class="form-control" value="up" required="true" name="Thumbs[rate]" id="topic" placeholder="topic">
<?= Html::submitButton('Save', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
<button type="submit" id="save" name="save">enter</button>
<?php ActiveForm::end(); ?>
<?php $form = ActiveForm::begin(['id' => "contact-form",
'enableClientValidation' => false,
]);
?>
<input type="hidden" class="form-control" hidden="true" value="down" required="true" name="Thumbs[rate]" id="topic" placeholder="topic">
<?= Html::submitButton('Save', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
<?php ActiveForm::end(); ?>
if you notice i seem to have kept the value of up and down in a input with type hidden. just want to know of a better way to do it.
this is my controller function
public function actionBlog()
{
$thumbs= new Thumbs();
$thumbs->user=Yii::$app->user->identity->email;
$thumbs->topic_id = '1';
if ($thumbs->load(Yii::$app->request->post()) && $thumbs->validate()) {
$thumbs->load($_POST);
$thumbs->save();
return $this->refresh();
}
return $this->render('blog');
}
i also tried to used ajax but it seems not to be working well

You can use Pjax for this.
Here is a simple example that you should be able to apply to your problem. I have included some comments for clarity, but I would heavily advise checking out this tutorial for further information and some extended examples.
View (vote.php):
<?php
use yii\widgets\Pjax;
use yii\helpers\Html;
use common\models\Thumbs;
?>
<?php Pjax::begin(['enablePushState' => false]); ?>
<?= Html::a('', ['site/upvote'], ['class' => 'btn btn-lg btn-warning glyphicon glyphicon-arrow-up']) ?>
<?= Html::a('', ['site/downvote'], ['class' => 'btn btn-lg btn-primary glyphicon glyphicon-arrow-down']) ?>
<h1><?= Thumbs::find()->where(['=', 'post_id', '1'])->one()->votes ?></h1>
<?php Pjax::end(); ?>
SiteController:
public function actionVote()
{
return $this->render('vote');
}
public function actionUpvote()
{
// find the thumbs record for the related post
$thumbsRecord = Thumbs::find()->where(['=', 'post_id', '1'])->one();
// increment the thumbs count
$thumbsRecord->votes += 1;
// ensure change persists to db
$thumbsRecord->save();
// return value to the view
return $this->render('vote', [
'votes' => $thumbsRecord->votes,
]);
}
/**
* Similar functionality to actionUpvote
*/
public function actionDownvote()
{
$thumbsRecord = Thumbs::find()->where(['=', 'post_id', '1'])->one();
$thumbsRecord->votes -= 1;
$thumbsRecord->save();
return $this->render('vote', [
'votes' => $thumbsRecord->votes,
]);
}
The model is just a table that contains the following fields:
id (int, primary key)
post_id (int)
votes (int, default 0)

Related

Yii2 - Show/Hide Fields on Form based on dropDown selection on form

I am new to Yii2 and have been trying to work out how to hide/show certain fields on the form based on a dropDownList selection with client-side validation.
Basically I have a model and form view that collects information relating to 'candidates' and I wish to apply the following logic:
Only display the fields 'assigned_to' and 'phone' if the dropDownList selection for 'qualification_id' = 2.
The fields 'assigned_to' and 'phone' are required if 'qualification_id' = 2 (else optional)
My code is as follows, albeit not working as I need it to. The client-side validation is not working (i.e.'assigned_to' and 'phone' are not required when qualification_id = 2). I have not been able to work out how to hide/show the fields dynamically based on the 'qualification_id' selection. I assume some javascript is required for this.
Any assistance would be greatly appreciated!
MODEL:
namespace frontend\models;
use Yii;
/**
* This is the model class for table "candidate".
*
* #property int $candidate_id
* #property string $name
* #property int $qualification_id
* #property string $assigned_to
* #property string $phone
public static function tableName()
{
return 'candidate';
}
public function rules()
{
return [
[['candidate_id', 'qualification_id', 'name'], 'required']
[['candidate_id', 'qualification_id'], 'integer'],
[['name', 'assigned_to’, 'phone’], 'string'],
[['assigned_to', 'phone'],'required','when'=>function($model){
return ($model->qualification_id == 2);
},
'whenClient'=>"function(attribute, value){
return $('#qualification_id').val() == 2;
}"],
VIEW (form):
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use frontend\models\QualificationType;
/* #var $this yii\web\View */
/* #var $model frontend\models\Candidate */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="candidate-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'qualification_id')->dropDownList(
ArrayHelper::map(QualificationType::find()->all(),'qualification_id','qualification'),
[
'prompt'=>'Select...',
'id' => 'review_type_id',
'onchange' => 'changeQualification()'
]
) ?>
<?= $form->field($model, 'assigned_to')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'phone')->textInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
$script = <<<JS
function changeQualification() {
if ($('#qualification_id').val() == 2) {
$('#assigned_to').show();
$('#name).show();
} else {
$('#assigned_to).hide();
$('#name).hide();
}
}
JS;
$this->registerJs($script);
?>
Please try like this
In view
<div class="candidate-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'qualification_id')->dropDownList(
ArrayHelper::map(QualificationType::find()->all(),'qualification_id','qualification'),
['prompt'=>'Select...', 'id' => 'qualification_id', 'onchange' => 'changeQualificationType()']
) ?>
<?= $form->field($model, 'assigned_to)->textInput(['id' => 'assigned_to_Input', 'maxlength' => true]) ?>
<?= $form->field($model, 'phone')->textInput(['id' => 'phone_input', 'maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
$script = <<<JS
function changeQualificationType() {
if ($('#qualification_id').val() == 2) {
$('#assigned_to_input').closest('.form-group').show();
$('#phone_input').closest('.form-group').show();
} else {
$('#assigned_to_input').closest('.form-group').hide();
$('#phone_input').closest('.form-group').hide();
}
}
JS;
$this->registerJs($script);
In Model
public function rules()
{
return [
[['candidate_id', 'qualification_id', 'name'], 'required']
[['candidate_id', 'qualification_id'], 'integer'],
[['name', 'assignedTo, 'phone’], 'string'],
[['assignedTo', 'phone'],'required','when'=>function($model){
return ($model->qualification_id == 2);
},
'whenClient'=>"function(attribute, value){
return $('#qualification_id').val() == 2;
}"],
Don't forget to set custom id in ActiveFormField. All of field id should be matched with functions of Jquery and Model.

Click on button and add new input fields Yii2

I have a doubt. Every time I press a button, I want it to add two more fields. But since I'm working with the yii2 framework I have difficulty implementing the javascript code along with the code of forms that the framework automatically creates.
My form created by gii
<div class="hotel-form">
<?php $form = ActiveForm::begin(); ?>
<center>
<?= $form->field($model, 'nome')->textInput(['maxlength' => true, 'style'=>'width:500px', 'placeholder' => "Nome do hotel"])->label(false); ?>
<!--
<?= $form->field($model, 'userId')->textInput(['maxlength' => true,'style'=>'width:500px', 'placeholder' => "Proprietário"])->label(false); ?>
-->
<?= $form->field($model, 'descricao')->textarea(['maxlength' => true, 'style'=>'width:500px; resize: none;', 'rows' => 6, 'placeholder' => "Descrição"])->label(false); ?>
<?= $form->field($model, 'contacto')->textInput([ 'maxlength' => 9, 'style'=>'width:500px','placeholder' => "Contacto"])->label(false); ?>
<?= $form->field($model, 'website')->textInput(['maxlength' => true, 'style'=>'width:500px', 'placeholder' => "Website"])->label(false); ?>
<?= $form->field($model, 'cp4')->textInput(['maxlength' => 4, 'style'=>'width:500px','placeholder' => "Código-postal (4 dígitos) "])->label(false); ?>
<?= $form->field($model, 'cp3')->textInput(['maxlength' => 3, 'style'=>'width:500px', 'placeholder' => "Código-postal (3 dígitos)"])->label(false); ?>
<?= $form->field($model, 'regiaoId')->dropDownList(ArrayHelper::map(RegiaoHotel::find()->orderBy(['nome' => SORT_ASC])->all(), 'id', 'nome'), ['style'=>'width:500px']) ?>
<?= $form->field($model, 'morada')->textInput(['maxlength' => true, 'style'=>'width:500px', 'placeholder' => "Morada"])->label(false); ?>
<?= $form->field($model, 'estado')->hiddenInput(['value'=> 2])->label(false);?>
<?= $form->field($model, 'img')->fileInput() ?>
//There are the fields i want do add each time i click button
<?= $form->field($comHotel, 'descricao')->textInput(['maxlength' => true, 'style'=>'width:500px', 'placeholder' => "Descricao comodidade"])->label(false);?>
<?= $form->field($comHotel, 'preco')->textInput(['maxlength' => true, 'style'=>'width:500px', 'placeholder' => "Preço da comodidade"])->label(false);?>
//
<br>
<div class="form-group">
<?= Html::submitButton('Registar', ['class' => 'btn btn-success']) ?>
</div>
</center>
<?php ActiveForm::end(); ?>
And there i have the js code that im trying to implement
<script>
var count = 1; // There are 4 questions already
function addQuestion()
{
// Get the quiz form element
var quiz = document.getElementById('quiz');
// Good to do error checking, make sure we managed to get something
if (quiz)
{
if (count)
{
// Create a new <p> element
var newP = document.createElement('p');
newP.innerHTML = 'Question ' + (count + 1);
// Create the new text box
var newInput = document.createElement('input');
newInput.type = 'text';
newInput.name = 'descricao';
var newInput1 = document.createElement('input');
newInput1.type = 'number';
newInput1.name = 'preco';
// Good practice to do error checking
if (newInput && newInput1 && newP)
{
// Add the new elements to the form
quiz.appendChild(newP);
quiz.appendChild(newInput);
quiz.appendChild(newInput1);
// Increment the count
count++;
}
}
else
{
alert('Question limit reached');
}
}
}
<form id="quiz" action="" method="POST">
<input type="button" value="Add question" onclick="javascript:
addQuestion();"/>
<p>Question 1</p>
<input type="text" name="descricao"/>
<input type="text" name="preco"/>
<p></p>
</form>
here is your perfect solution for dynamically add or remove fields with perfect exmaple
yii2-dynamicform

How to Overcome Conflicts in JS

In form, I want the function to take data from form one to another form automatically and automatic calculations run together. but here only one function can be run.
in my foto I want when I select LAO, it will automatically retrieve data from other forms and appear in the Posisi Awal textfield. then when I fill the Persen textfield, then automatically calculates and fills in the data from the calculation of the Posisi Awal with Persen in the Target Awal textfield. The problem is the automatic calculation works but retrieving data from the form to another form does not work.
<?= $form->field($model, 'posisi_awal')->textInput(['id'=>'posisi_awal','onkeyup'=>'sum();','type' => 'number','maxlength' => true])->label('Posisi Awal') ?>
when I omit 'id' => 'posisi_awal' in this code. for the function of retrieving data from another location it can run, but for automatic calculations it cannot
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use app\models\Resumes;
use dosamigos\datepicker\DatePicker;
/* #var $this yii\web\View */
/* #var $model app\models\Monitoring */
/* #var $form yii\widgets\ActiveForm */
$model->tgl = date('Y-m-d');
?>
<script>
function sum() {
var txtThirdNumberValue = document.getElementById('posisi_awal').value;
var txtFourNumberValue = document.getElementById('persen').value;
var result1 = parseInt(txtThirdNumberValue) / 100 * parseInt(txtFourNumberValue);
var hasil1 = Math.ceil(result1);
if (!isNaN(hasil1)) {
document.getElementById('target_awal').value = hasil1;
}
}
</script>
<div class="monitoring-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'kode_lao')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Resumes::find()->all(),'resumes_id',function($model){return ($model->lao.' ('.$model->tgl.')');}),
'theme' => Select2::THEME_BOOTSTRAP,
'language' => 'en',
'options' => ['placeholder' => 'Pilih LAO (Tanggal)','required' => true,'style'=>'width:500px','maxlength' => true,'id'=>'lao'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?= $form->field($model, 'tgl')->textInput(['readOnly'=>true,'style'=>'width:500px','maxlength' => true]) ?>
<?= $form->field($model, 'posisi_awal')->textInput(['id'=>'posisi_awal','onkeyup'=>'sum();','type' => 'number','maxlength' => true])->label('Posisi Awal') ?>
<?= $form->field($model, 'persen')->textInput(['id'=>'persen','onkeyup'=>'sum();','type' => 'number','maxlength' => true])->label('Persen') ?>
<?= $form->field($model, 'target_awal')->textInput(['id'=>'target_awal','onkeyup'=>'sum();','type' => 'number','maxlength' => true])->label('Target Awal') ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
$script = <<< JS
$('#lao').change(function(){
var laoId = $(this).val();
$.get('index.php?r=resumes/get-persen-eom',{ laoId : laoId },function(data){
var data = $.parseJSON(data);
$('#monitoring-tgl').attr('value',data.tgl);
$('#monitoring-posisi_awal').attr('value',data.tgt_pergeseran);
});
});
JS;
$this->registerJs($script);
?>
$('#monitoring-tgl').attr('value',data.tgl);
$('#monitoring-posisi_awal').attr('value',data.tgt_pergeseran);
You don't have fields with those ID's on that page.
Also if you change some input value then you need to trigget a change event on that input for other code that is reliant on that fields onchange event to trigger.
Why are you changing value of an input using attr? jQuery has .val(value) method for this: http://api.jquery.com/val/
So correct usage would be something like this:
$('#monitoring-tgl').val(data.tgl).trigger("change");
$('#monitoring-posisi_awal').val(data.tgt_pergeseran).trigger("change");
Or maybe even like this. As I think you are refering to the #posisi_awal input there actually. But I dont have a clue about #monitoring-tgl input. Does not seem to exist on that page.
$('#monitoring-tgl').val(data.tgl).trigger("change");
$('#posisi_awal').val(data.tgt_pergeseran).trigger("change");

YII2 PJAX and javascript function call action from controller

I implement below example for autorefresh of time.(only interval function is set for one sec)
http://blog.neattutorials.com/examples/pjax/web/site/auto-refresh
I use this implementation on my VIEW where i use Inputform and i have trouble that each reload i lost pointer from inputform.
Please is there some way, how Javascript can call function from controller without using button or how i can reload part of page without losing pointer from my text input??
I tried window.location.replace("site/auto-refresh"); but it refresh whole site, and not part of PJAX.
There is my code:
<?php $form = ActiveForm::begin(['id' => 'my-form']);
echo $form->field($model,'ipadress')->textInput((['id'=>'ipadress'])); $model->text = $text;
echo $form->field($model, 'text')->textArea(['rows' => '6','readonly' => 'true']);
echo Html::submitButton('Submit',['class'=>'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
<?php Pjax::begin(); ?>
<?= Html::a("Refresh", ['site/auto-refresh'], ['class' => 'btn btn-lg btn-primary', 'id' => 'refreshButton',]) ?>
<h1>Current time: <?= $time ?></h1>
<?php Pjax::end(); ?>
<?php
$script = <<< JS
$(document).ready(function() {
setInterval(function(){ $("#refressetIntervalhButton").click(); }, 1000);
});
JS;
$this->registerJs($script);
?>
UPDATE:
Still the same result, when time is updated i lost pointer from text input(when i writting).
VIEW:
<?php $form = ActiveForm::begin(['id' => 'my-form']); ?>
<?php echo $form->field($model,'ipadress')->textInput((['id'=>'ipadress']));
$model->text = $text; ?>
<?= $form->field($model, 'text')->textArea(['rows' => '6','readonly' => 'true']) ?>
<?= Html::submitButton('Submit',['class'=>'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
<?php Pjax::begin(); ?>
<?= Html::a("Refresh", ['site/auto-refresh'], ['class' => 'btn btn-lg btn-primary', 'id' => 'refreshButton',]) ?>
<h1>Current time: <?= $model->time ?></h1>
<?php Pjax::end(); ?>
Controller:
$model = new \app\models\Tools;
$model->time = date('H:i:s');
$uptime=shell_exec('uptime | awk \'{print $3}\';');
return $this->render('auto-refresh', ['uptime' => $uptime, 'text' => $ip,'model' => $model]
Thank you
MK
Please use one controller action for both and add time as public property in your model.
Controller
public function actionTest()
{
$model = new Test();
$model->time = date('H:i:s');
return $this->render('TestView', ['model' =>$model]);
}
View
<?php Pjax::begin(); ?>
<?= Html::a("Refresh", ['site/test'], ['class' => 'btn btn-lg btn-primary', 'id' => 'refreshButton',]) ?>
<h1>Current time: <?= $model->time ?></h1>
<?php Pjax::end(); ?>
Or you don't want time as public property your controller return like below
return $this->render('TestView', ['model' => $model,'time'=>date('H:i:s')]);
And use time variable in view directly.

Yii2 inputfield set disabled depend other field

I have, a create form, where i ask two things.
The first is a user_id the other is a name.
I want to achieve that, if the first is set then the other field will be disabled.
And if because there i want to save that specific user's name.
I tried it with javascript, but im so noob with js, thats why ask to you.
My codes is that:
$script = <<<JS
$('#contact-user_id').on('afterValidate', function (e) {
if ( $('#contact-user_id').value.length > 0 ) {
return document.getElementById("contact-name").disabled = true;
}
});
JS;
$this->registerJs($script);
?>
<div class="row">
<div class="col-md-6">
<?= $form->field($model, 'user_id')->widget(Select2::className(), [
'value' => $model->user_id,
'data'=>ArrayHelper::map(User::find()->all(), 'user_id', 'name'),
'options'=>['placeholder'=>'Select User...'],
'pluginOptions' => [
'allowClear' => true
],
]) ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>
...
First of all, add the script at the bottom of your view or add it into the $(document).ready();
Now, the code to change the name field depending upon user_id field.
$('#contact-user_id').change(function(){
if ($(this).val() != 0 || $(this).val() != '') {
$('#contact-name').attr('disabled',true);
}
});

Categories