I want to search field in my application. I have penerimaan_table. There are rm_code, quantity, bulan, price fields.
How to show my result like this:
rm_code bulan
k123 7
k123 4
k123 5
When I filter I want just show bulan 7 & 5
k123 7
k123 5
How can I do this?
This is my view:
<?php
use yii\helpers\Html;
use kartik\grid\GridView;
use kartik\export\ExportMenu;
/* #var $this yii\web\View */
/* #var $searchModel backend\models\PenerimaanSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Penerimaan Raw Material';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="penerimaan-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a('Tambah Penerimaan Raw Material', ['create'], ['class' => 'btn btn-success']) ?>
<?= Html::a('Import Penerimaan', ['import'], ['class' => 'btn btn-success']) ?>
</p>
<p><font color="red">Deskripsi Barang yang kosong merupakan Barang Baru!!</p></font>
<?php
echo ExportMenu::widget([
'dataProvider' => $dataProvider,
'columns' => [
// 'id',
'rm_code',
'rmCode.deskripsi_barang',
'saldo_awal',
'quantity',
'bulan',
//'price',
'total'
],
'showPageSummary' => true,
]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'kartik\grid\SerialColumn'],
// 'id',
'rm_code',
'rmCode.deskripsi_barang',
// 'saldo_awal',
'quantity',
'bulan',
[
'attribute' => 'price',
'label' => 'Price',
'footer' => $myAverage,
],
//'price',
[
'label' => 'Total',
'attribute' => 'total',
'pageSummary' => true,
// 'pageSummaryOptions' => ['id_layanan' => 'deskripsi'],
'value' => function ($model) {
if($model)
return $model->total ;
else
return 0;
}
],
['class' => 'kartik\grid\ActionColumn'],
],
'showPageSummary' => true,
]); ?>
<?php echo"Harga Rata-rata Barang adalah:";
$myAverage = 0;
$myTot =0;
$myCnt = 0;
$data = $dataProvider->getModels();
foreach ($data as $key => $value) {
$myTot += $value['price'];
$myCnt++;
}
if ($myCnt>0){
$myAverage = $myTot/$myCnt;
}
echo $myAverage; // your average displayed herre, you can place it wherever you want.
?>
<?php
$this->registerJs("
// 1. Dapatkan handle dari tabel gridview
table = $('div.grid-view > table');
// 2. Hitung kolom tertentu, pada contoh ini menghitung nilai total pada kolom ke 3
var sum = 0;
table.find('tbody').find('tr').each(function() {
sum += parseInt($(this).find('td:nth-child(4)').text());
});
// 3. Tampilkan hasil perhitungan pada tabel baris terakhir kolom ke 3
table.find('tfoot > tr > td:nth-child(4)').text(sum);
");
?>
</div>
Problem 1: the validators
Within your PenerimaanSearch-model remove the integer-validator for the bulan-field. And add two new ones as follows:
public function rules() {
//...
[['bulan'], 'integer', 'when'=>function($model) {
return strpos($model->bulan, '&') === false;
}],
[['bulan'], 'string', 'when'=>function($model) {
return strpos($model->bulan, '&') !== false;
}],
//...
}
This will only validate your field as an integer when no &is present. Otherwise it will use a string validator. The optimal way would be a regex-v& onle, but I'm sure you'll figure out how to do so.
Problem 2: functionality within the Search model
Again in the BulanSearch you can find the search()-method which is responsible for filtering the result by attributes. Remove all operations concerning the bulan-field and instead use the following:
public function search($params)
{
//...
if (!empty($this->bulan)) {
if (strpos($this->bulan, '&') !== false) {
$bulan = $this->bulan;
} else {
//filter with int
$bulan = explode('&', $this->bulan);
}
$this->andFilterWhere(['bulan'=>$bulan]);
}
//...
}
That should do the trick. The andFilterWhere decides itself whether to use an IN-condition (multiple values) or a regular comparison (single value).
This should do the trick! However, tell me if you have problems. I'll be happy to help!
Related
I did a simple gridview table with filters on yii2, seems to be working great, but I noticed the javascript functions doesn't work after I apply any filter on the gridview table, i think its refreshing the whole page instead only refresh the table.
I did the $.pjax.reload method but it didn't work, this is how i applied the pjax reload method:
//inventariosearch-amb_id is the ID of one of my filterselects on the gridview
$("#inventariosearch-amb_id").on("pjax:end", function() {
$.pjax.reload({container:"#inventario_lista"}); //Reload GridView
});
Let me know if i applied wrong the method.
well, as I said I think the pjax is refreshing the whole page cause it changes my page title from this:
To this:
That's how I notice the changes and the javascript doesn't work properly anymore.
What can I do?.
My view index.php:
<?php
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
use yii\grid\GridView;
use yii\grid\ActionColumn;
use yii\widgets\Pjax;
use yii\bootstrap4\Modal;
use app\models\Ambiente;
use app\models\TipoServicio;
use app\models\Empresa;
/* #var $this yii\web\View */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->registerJsFile("#web/js/inventario.js",[
'depends' => [
\yii\web\JqueryAsset::className()
]
]);
$this->title = 'Servidores';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="inventario-index">
<?php $this->beginBlock('bloque_titulo'); ?>
<div class="page-title-icon">
<i class="fa fa-archive icon-gradient bg-arielle-smile">
</i>
</div>
<div>
<?= Html::encode($this->title) ?>
<div class="page-title-subheading">
Lista de servidores
</div>
</div>
<?php $this->endBlock(); ?>
<p>
<?= Html::a('<i class="fa fa-plus"></i> Añadir nuevo', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?php Pjax::begin(['id'=>'inventario_lista','timeout'=> false,'clientOptions' => ['method' => 'POST','registerClientScript' => 'alert("lol")']]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $model,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'attribute' => 'amb_id',
'value' => 'amb.amb_desc',
'filter' => Html::activeDropDownList($model, 'amb_id', ArrayHelper::map(Ambiente::find()->asArray()->all(), 'amb_id', 'amb_desc'), [
'class' => 'form-control',
'prompt' => '--- Seleccione ---'
])
],
'inv_plataforma',
'inv_host_computername',
[
'attribute' => 'tise_id',
'value' => 'tise.tise_desc',
'filter' => Html::activeDropDownList($model, 'tise_id',ArrayHelper::map(TipoServicio::find()->orderby(['tise_desc'=>SORT_ASC])->asArray()->all(), 'tise_id', 'tise_desc'), [
'class' => 'form-control',
'prompt' => '--- Seleccione ---'
])
],
[
'attribute' => 'emp_id',
'value' => 'emp.emp_desc',
'filter' => Html::activeDropDownList($model, 'emp_id',ArrayHelper::map(Empresa::find()->orderby(['emp_desc'=>SORT_ASC])->asArray()->all(), 'emp_id', 'emp_desc'), [
'class' => 'form-control',
'prompt' => '--- Seleccione ---'
])
],
//'inv_servicio',
//'inv_ip_admin',
//'inv_ip_servicio',
//'inv_ip_nfs',
//'sad_id',
//'usu_id_responsable_sistema',
//'usu_id_2doresponsable_sistema',
//'inv_modelo_servidor',
//'prov_id',
//'inv_serial_equipo',
//'inv_codigo_remedy',
//'inv_serial_dispositivo',
//'sop_id',
//'inv_version_so',
//'inv_alta_disponibilidad',
//'inv_ubicacion',
//'inv_ala',
//'inv_fila',
//'inv_rack',
//'inv_cpu_core',
//'inv_cpu_modelo',
//'inv_cpu_velocidad',
//'inv_gb_memoria',
//'hat_id',
//'inv_tipo_contrato_proveedor',
//'inv_responsable_funcional',
//'spa_id',
//'fv_id',
//'pr_id',
//'inv_observaciones',
//'inv_performance_review',
//'inv_performance_management',
//'inv_obsoleto',
//'inv_motivo_obsoleto',
//'inv_arbol',
//'inv_arbol_1er_nivel',
//'inv_fin_venta',
//'inv_fin_partes',
//'inv_fin_soporte',
//'inv_fecha_cons_obsoleto',
['class' => 'yii\grid\ActionColumn',
'buttons'=>[
'view'=>
function($url,$model,$key){
$btn = Html::button("<i class='fa fa-eye'></i>",[
'value'=>Yii::$app->urlManager->createUrl('inventario/view/'.$key),
'class'=>'serverview grid-action btn btn-info',
'title'=>'Ver datos del servidor',
'data-toggle'=> 'modal',
'data-target'=> '#modalviewserver',
]);
return $btn;
},
'update'=>function ($url,$model,$key) {
return Html::a('<i class="fa fa-edit"></i>', ['/inventario/update/'.$key], ['class'=>'btn btn-success grid-button']);
},
],
],
],
]); ?>
<?php Pjax::end(); ?>
</div>
<?php
Modal::begin([
'title' => '<h4>Ver servidor</h4>',
'id' => 'modalviewserver',
'size' => 'modal-lg',
]);
echo "<div id='viewservercontent'></div>";
Modal::end();
?>
My action controller:
public function actionIndex()
{
$model = new InventarioSearch();
$dataProvider = $model->search(Yii::$app->request->post());
return $this->render('index', [
'dataProvider' => $dataProvider,
'model' => $model
]);
}
And my JS (just in case):
$(document).ready(function ()
{
// $("#inventariosearch-amb_id").on("pjax:end", function() {
// $.pjax.reload({container:"#inventario_lista"}); //Reload GridView
// });
$('.serverview').click(function()
{
$('#modalviewserver').appendTo("body").modal('show')
.find('#viewservercontent')
.load($(this).attr('value'));
});
});
If you want your link to refresh whole page you have to remove your pjax.
Other way, try to set your javascript in pjax:success like this:
$(document).on('ready pjax:success', function(){
//your javascript here
$('.serverview').click(function()
{
$('#modalviewserver').appendTo("body").modal('show')
.find('#viewservercontent')
.load($(this).attr('value'));
});
})
I need to call a Javascript function before submitting a form, this function generates 2 values (1 token and 1 hash), so I need to pass these values in 2 hidden fields.
JS Function: FULL/UPDATED
<script type="text/javascript">
//Generates the necessary content
$('#submitForm').click(function() {
PagSeguroBuscaHashCliente(); //Create Hash
PagSeguroBuscaBandeira(); //By field "pagseguro_cartao_numero" return flag card
PagSeguroBuscaToken(); //By 4 digits "pagseguro_cartao_numero" gen token card
setTimeout(function() {
enviarPedido();
}, 3000);
});
function enviarPedido() {
/** TEST GENERATED VALUES **/
alert($('#pagseguro_cliente_hash').val())
alert($('#pagseguro_cartao_token').val())
// var data = {
// hash: $('#pagseguro_cliente_hash').val(),
// token: $('#pagseguro_cartao_token').val()
// };
$('#pagseguro_cliente_hash').val(pagseguro_cliente_hash);
$('#pagseguro_cartao_token').val(pagseguro_cartao_token);
$('#sampleForm').submit();
}
</script>
View form:
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\models\Assinatura;
use CWG\PagSeguro\PagSeguroAssinaturas;
$this->title = 'Assinatura';
$this->params['breadcrumbs'][] = $this->title;
$email = "xxxxxx#hotmail.com";
$token = "xxxxxxx";
// token gerado em 23/04/2020
$sandbox = false;
$pagseguro = new PagSeguroAssinaturas($email, $token, $sandbox);
//Sete apenas TRUE caso queira importa o Jquery também. Caso já possua, não precisa
$js = $pagseguro->preparaCheckoutTransparente(true);
echo $js['completo']; //Importa todos os javascripts necessários
?>
<div class="site-minhaconta">
<h1><?= Html::encode($this->title) ?></h1>
<!-- INICIO FORM -->
<?php $form = ActiveForm::begin([
'method' => 'post',
'id' =>'sampleForm'
])
?>
<div class="panel-body">
<?= $form->field($model, 'pagseguro_cartao_numero')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'pagseguro_cartao_mes')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'pagseguro_cartao_ano')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'pagseguro_cartao_cvv')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'form_nome')->textInput(['maxlength' => true]) ?>
<hr>
<?= $form->field($model, 'form_email')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'form_cpf')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'pagseguro_cliente_hash')->hiddenInput(['id' => 'pagseguro_cliente_hash'])->label(false)?>
<?= $form->field($model, 'pagseguro_cartao_token')->hiddenInput(['id' => 'pagseguro_cartao_token'])->label(false)?>
<div class="form-group">
<?= Html::button('Confirmar Assinatura', ['name'=>'submitForm',
'id' => 'submitForm', 'value'=>'submitForm', 'class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
<!-- FINAL FORM -->
<script type="text/javascript">
//Generates the necessary content
$('#submitForm').click(function() {
PagSeguroBuscaHashCliente(); //Create Hash
PagSeguroBuscaBandeira(); //By field "pagseguro_cartao_numero" return flag card
PagSeguroBuscaToken(); //By 4 digits "pagseguro_cartao_numero" gen token card
setTimeout(function() {
enviarPedido();
}, 3000);
});
function enviarPedido() {
/** TEST GENERATED VALUES **/
alert($('#pagseguro_cliente_hash').val())
alert($('#pagseguro_cartao_token').val())
// var data = {
// hash: $('#pagseguro_cliente_hash').val(),
// token: $('#pagseguro_cartao_token').val()
// };
$('#pagseguro_cliente_hash').val(pagseguro_cliente_hash);
$('#pagseguro_cartao_token').val(pagseguro_cartao_token);
$('#sampleForm').submit();
}
</script>
</div>
Controller Action:
public function actionAssinatura()
{
$model = new \app\models\Assinatura();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->form_email = $_POST['Assinatura']['form_email'];
$model->form_cpf = $_POST['Assinatura']['form_cpf'];
$model->pagseguro_cliente_hash = $_POST['Assinatura']['pagseguro_cliente_hash'];
$model->pagseguro_cartao_token = $_POST['Assinatura']['pagseguro_cartao_token'];
return $this->render('plano_assinatura_process', [
'form_email' => $model->form_email,
'form_cpf' => $model->form_cpf,
'pagseguro_cliente_hash' => $model->pagseguro_cliente_hash,
'pagseguro_cartao_token' => $model->pagseguro_cartao_token,
]);
} else {
return $this->render('plano_assinatura_form', [
'model' => $model,
]);
}
}
Model file
public $pagseguro_cartao_numero;
public $pagseguro_cartao_mes;
public $pagseguro_cartao_ano;
public $pagseguro_cartao_cvv;
public $form_nome;
public $form_email;
public $form_cpf;
public $form_plano;
public $form_codplano;
public $pagseguro_cartao_token;
public $pagseguro_cliente_hash;
public function rules()
{
return [
[[
'pagseguro_cartao_numero',
'pagseguro_cartao_mes',
'pagseguro_cartao_ano',
'pagseguro_cartao_cvv',
'form_nome',
'form_email',
'form_cpf',
'form_plano',
//'form_codplano',
], 'required'],
[['pagseguro_cartao_token', 'pagseguro_cliente_hash'], 'safe'],
];
}
The hidden fields "pagseguro_cliente_hash" and "pagseguro_cliente_token" need to receive the variables js $ ('# pagseguro_cliente_hash'). Val () and $ ('# pagseguro_cartao_token'). Val () respectively.
How do you do that?
Generated JS by Payment gateway (UPDATE 2020-05-09)
<script type="text/javascript" src="https://stc.pagseguro.uol.com.br/pagseguro/api/v2/checkout/pagseguro.directpayment.js"></script><script type="text/javascript">PagSeguroDirectPayment.setSessionId("336d21fd502c41c982c55faf90e1eba9")</script>
<input type='hidden' id='pagseguro_cliente_hash'/>
<script type='text/javascript'>
function PagSeguroBuscaHashCliente() {
PagSeguroDirectPayment.onSenderHashReady(function(response){
if(response.status == 'error') {
console.log(response.message);
return false;
}
$('#pagseguro_cliente_hash').val(response.senderHash); //Hash estará disponível nesta variável.
console.log('Hash Cliente: ' + $('#pagseguro_cliente_hash').val());
});
}
</script>
<input type='hidden' id='pagseguro_cartao_token' />
<script type='text/javascript'>
function PagSeguroBuscaToken() {
PagSeguroDirectPayment.createCardToken({
cardNumber: $('#pagseguro_cartao_numero').val(),
brand: $('#pagseguro_cartao_bandeira').val(),
cvv: $('#pagseguro_cartao_cvv').val(),
expirationMonth: $('#pagseguro_cartao_mes').val(),
expirationYear: $('#pagseguro_cartao_ano').val(),
success: function(response) { console.log('Token: ' + response.card.token); $('#pagseguro_cartao_token').val(response.card.token)},
error: function(response) { console.log(response); },
});
}
</script>
Payment Gateway example form page:
<h2> Campos Obrigatórios </h2>
<p>Número do Cartão</p>
<!-- OBRIGATÓRIO UM CAMPO COM O ID pagseguro_cartao_numero-->
<input type="text" id="pagseguro_cartao_numero" value="4111111111111111"/>
<p>CVV do cartão</p>
<!-- OBRIGATÓRIO UM CAMPO COM O ID pagseguro_cartao_cvv-->
<input type="text" id="pagseguro_cartao_cvv" value="123"/>
<p>Mês de expiração do Cartao</p>
<!-- OBRIGATÓRIO UM CAMPO COM O ID pagseguro_cartao_mes-->
<input type="text" id="pagseguro_cartao_mes" value="12"/>
<p>Ano de Expiração do Cartão</p>
<!-- OBRIGATÓRIO UM CAMPO COM O ID pagseguro_cartao_ano-->
<input type="text" id="pagseguro_cartao_ano" value="2030"/>
<br/>
<button id="botao_comprar">Comprar</button>
<script type="text/javascript">
//Gera os conteúdos necessários
$('#botao_comprar').click(function() {
PagSeguroBuscaHashCliente(); //Cria o Hash identificador do Cliente usado na transição
PagSeguroBuscaBandeira(); //Através do pagseguro_cartao_numero do cartão busca a bandeira
PagSeguroBuscaToken(); //Através dos 4 campos acima gera o Token do cartão
setTimeout(function() {
enviarPedido();
}, 3000);
});
function enviarPedido() {
/** FAÇA O QUE QUISER DAQUI PARA BAIXO **/
alert($('#pagseguro_cliente_hash').val())
alert($('#pagseguro_cartao_token').val())
var data = {
hash: $('#pagseguro_cliente_hash').val(),
token: $('#pagseguro_cartao_token').val()
};
$.post('http://localhost/pagseguro/examples/assinando2.php', data, function(response) {
alert(response);
});
}
</script>
plano_assinatura_form:
<?php $form = ActiveForm::begin([
'method' => 'post',
'id' =>'sampleForm'
])
?>
<div class="panel-body">
<?= $form->field($model, 'pagseguro_cartao_numero')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'pagseguro_cartao_mes')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'pagseguro_cartao_ano')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'pagseguro_cartao_cvv')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'form_nome')->textInput(['maxlength' => true]) ?>
<hr>
<?= $form->field($model, 'form_email')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'form_cpf')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'pagseguro_cliente_hash')->hiddenInput(['id' => 'pagseguro_cliente_hash'])->label(false)?>
<?= $form->field($model, 'pagseguro_cartao_token')->hiddenInput(['id' => 'pagseguro_cartao_token'])->label(false)?>
<div class="form-group">
<?= Html::button('Confirmar Assinatura', ['name'=>'submitForm',
'id' => 'submitForm', 'value'=>'submitForm', 'class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
<!-- FINAL FORM -->
<?php $this->registerJsFile(Yii::$app->request->baseUrl.'/test.js',['depends' => [\yii\web\JqueryAsset::className()]]); ?>
test.js:
$('#submitForm').click(function() {
// PagSeguroBuscaHashCliente(); //Create Hash
// PagSeguroBuscaBandeira(); //By field "pagseguro_cartao_numero"
return flag card
// PagSeguroBuscaToken(); //By 4 digits
"pagseguro_cartao_numero" gen token card
setTimeout(function() {
enviarPedido();
}, 3000);
});
function enviarPedido() {
/** TEST GENERATED VALUES **/
pagseguro_cliente_hash = 'testHash';
pagseguro_cartao_token = 'testToken';
// var data = {
// hash: $('#pagseguro_cliente_hash').val(),
// token: $('#pagseguro_cartao_token').val()
// };
$('#pagseguro_cliente_hash').val(pagseguro_cliente_hash);
$('#pagseguro_cartao_token').val(pagseguro_cartao_token);
alert($('#pagseguro_cliente_hash').val())
alert($('#pagseguro_cartao_token').val())
$('#sampleForm').submit();
}
actionAssinatura:
public function actionAssinatura()
{
$model = new \app\models\Assinatura();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->form_email = $_POST['Assinatura']['form_email'];
$model->form_cpf = $_POST['Assinatura']['form_cpf'];
$model->pagseguro_cliente_hash = $_POST['Assinatura']['pagseguro_cliente_hash'];
$model->pagseguro_cartao_token = $_POST['Assinatura']['pagseguro_cartao_token'];
return $this->render('plano_assinatura_process', [
'form_email' => $model->form_email,
'form_cpf' => $model->form_cpf,
'pagseguro_cliente_hash' => $model->pagseguro_cliente_hash,
'pagseguro_cartao_token' => $model->pagseguro_cartao_token,
]);
} else {
return $this->render('plano_assinatura_form', [
'model' => $model,
]);
}
}
fetch posted data in assinatura action :
C:\wamp64\www\basic\controllers\SiteController.php:139:
array (size=2)
'_csrf' => string 'C1spbi8HWaBqAO0w5ozFK6KOyKb20j0cRGR_j5t6vEg-FBE-
bXRs8gFZqVSOwp9xyOrl8sHleHUCMQv89CXxeQ==' (length=88)
'Assinatura' =>
array (size=9)
'pagseguro_cartao_numero' => string 'asdfasdf' (length=8)
'pagseguro_cartao_mes' => string 'asdfasdf' (length=8)
'pagseguro_cartao_ano' => string 'asdfasdf' (length=8)
'pagseguro_cartao_cvv' => string 'asdfasdf' (length=8)
'form_nome' => string 'asdfasdf' (length=8)
'form_email' => string 'asdfasdf' (length=8)
'form_cpf' => string 'asdfasdf' (length=8)
'pagseguro_cliente_hash' => string 'testHash' (length=8)
'pagseguro_cartao_token' => string 'testToken' (length=9)
In case of Yii
You should add below form structure using ActiveForm
<?php $form = ActiveForm::begin([
'id'=>'YourFormId'
]) ?>
//input fields and buttons
<?php ActiveForm::end() ?>
Simply add below code to execute your JS before form submitting
$('body').on('beforeSubmit',"#YourFormId",function() {
//javascript code here
});
return false; to stop form submitting
for more details Click Here
I want to show the sum of a gridview column in a textbox. When the page loads, the sum should pass to the textbox.
I've written the following javascript code in my index.php file. But not getting the sum. The javascript code might not be correct. Please let me know how to do it -
index.php -
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel frontend\modules\sgledger\models\SellitemsgSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Sunglass Ledger';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="sellitemsg-index">
<h1>Sunglass Ledger</h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<div class= 'col-md-6'>
<?= GridView::widget([
'id' => 'purchasetable',
'dataProvider' => $dataProvider2,
'filterModel' => $searchModel2,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'poisg_id',
[
'attribute' => 'Date',
'value' => 'posg.posg_date'
],
'posg_invno',
[
'attribute' => 'Vendor',
'value' => 'posg.posg_vname'
],
//'poisg_sgname',
'poisg_qty',
//['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
<div class= 'col-md-6'>
<?= GridView::widget([
'id' => 'selltable',
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'ssgi_id',
[
'attribute' => 'Date',
'value' => 'sellsg.ssg_date'
],
'ssgi_invoiceno',
[
'attribute' => 'Customer',
'value' => 'sellsg.ssg_customer'
],
//'ssgi_sgname',
//'ssgi_price',
//['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
</div>
<?php
/* start getting the textboxes */
$script = <<< JS
$(document).on('ready', function(e) {
var purgrid = purchasetable.getElementsByTagName('poisg_qty');
var total0 = 0;
for (var i = 0; i < purgrid.length; i++) {
var totp = purgrid[i].value
total0 = parseInt(total0) + parseInt(totp);
}
// ^ This number takes (n+1)th column
console.log('First table total value: ' + total0);
})
JS;
$this->registerJs($script);
/* end getting the textboxes */
?>
Present output -
Could be you can use showFooter for gridView
Firts you ca can calculate the value using the dataProvider
$yourTotal =0;
$numRow = 0;
foreach ($dataProvider->models as $key => $value) {
$yourTotal += $value['your_attribute'];
$numRow++;
}
Then in GridView you can set showFooter => TRUE and in the column you need you can add footer (and eventually footerOptions)
echo GridView::widget([
'dataProvider' => $dataProvider,
......
'showFooter'=>TRUE,
.....
'columns' => [
['class' => 'yii\grid\SerialColumn'],
......
[ 'attribute' => 'your_attribute',
'label' => 'Your Lable',
'footer' => $yourTotal,
'footerOptions' => ['style' => 'text-align:right;'],
],
........
and you can add you text using input
<?= Html::textInput('your_name', $yourTotal , options[]); ?>
or you can add a simple div
<div id='my_id'> <?= $yourTotal ?> </div>
In my project, I have an aggregation between, let's say, a University model and a Department model: a university have at least one department, while every department belongs to only one university.
I'd like to have a possibility to create a university model instance with some number of department model instances and the exact number of departments is not known in advance (but at least one must exist). So, when creating a university, I'd like to have a page with one default department and an "Add Department" button that would allow me by means of javascript to add any number of departments that I need.
The question is: how should I write the create view page using ActiveForm in order that my POST array has the following structure:
"University" => ["name" => "Sorbonne", "city" => "Paris"],
"Faculty" => [
0 => ["name" => "Medicine", "dean" => "Person A"],
1 => ["name" => "Physics", "dean" => "Person B"],
2 => ["name" => "Mathematics", "dean" => "Person C"],
...
]
that I then pass to Faculty::loadMultiple() method.
I've tried something like this
$form = ActiveForm::begin();
echo $form->field($university, 'name')->textInput();
echo $form->field($university, 'city')->textInput();
foreach ($faculties as $i => $faculty) {
echo $form->field($faculty, "[$i]name")->textInput();
echo $form->field($faculty, "[$i]dean")->textInput()
}
ActiveForm::end();
It works, but when adding new department by means of javascript (I just clone an html node that contains department input fields), I am forced to elaborate the numbers coming from variable $i of the above php script. And this is quite annoying.
Another possibility that I've tried was to get rid of variable $i and write something like
$form = ActiveForm::begin();
echo $form->field($university, 'name')->textInput();
echo $form->field($university, 'city')->textInput();
foreach ($faculties as $faculty) {
echo $form->field($faculty, "[]name")->textInput();
echo $form->field($faculty, "[]dean")->textInput()
}
ActiveForm::end();
In this way, cloning the corresponding node is very simple, but the generated POST array has wrong structure due to [] brackets.
Is it possible to modify the latter approach and to have the required structure of the POST array?
Use Yii2 dynamic form extension:
Installation
The preferred way to install this extension is through composer.
Either run:
composer require --prefer-dist wbraganca/yii2-dynamicform "dev-master"
Or add to the require section of your composer.json file:
"wbraganca/yii2-dynamicform": "dev-master"
Demo page: Nested Dynamic Form
Nested Dynamic Form Demo Source Code:
Source Code - View: _form.php
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
?>
<div class="person-form">
<?php $form = ActiveForm::begin(['id' => 'dynamic- form']); ?>
<div class="row">
<div class="col-sm-6">
<?= $form->field($modelPerson, 'first_name')->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-6">
<?= $form->field($modelPerson, 'last_name')->textInput(['maxlength' => true]) ?>
</div>
</div>
<div class="padding-v-md">
<div class="line line-dashed"></div>
</div>
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper',
'widgetBody' => '.container-items',
'widgetItem' => '.house-item',
'limit' => 10,
'min' => 1,
'insertButton' => '.add-house',
'deleteButton' => '.remove-house',
'model' => $modelsHouse[0],
'formId' => 'dynamic-form',
'formFields' => [
'description',
],
]); ?>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Houses</th>
<th style="width: 450px;">Rooms</th>
<th class="text-center" style="width: 90px;">
<button type="button" class="add-house btn btn-success btn-xs"><span class="fa fa-plus"></span></button>
</th>
</tr>
</thead>
<tbody class="container-items">
<?php foreach ($modelsHouse as $indexHouse => $modelHouse): ?>
<tr class="house-item">
<td class="vcenter">
<?php
// necessary for update action.
if (! $modelHouse->isNewRecord) {
echo Html::activeHiddenInput($modelHouse, "[{$indexHouse}]id");
}
?>
<?= $form->field($modelHouse, "[{$indexHouse}]description")->label(false)->textInput(['maxlength' => true]) ?>
</td>
<td>
<?= $this->render('_form-rooms', [
'form' => $form,
'indexHouse' => $indexHouse,
'modelsRoom' => $modelsRoom[$indexHouse],
]) ?>
</td>
<td class="text-center vcenter" style="width: 90px; verti">
<button type="button" class="remove-house btn btn-danger btn-xs"><span class="fa fa-minus"></span></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php DynamicFormWidget::end(); ?>
<div class="form-group">
<?= Html::submitButton($modelPerson->isNewRecord ? 'Create' : 'Update', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Source Code - View: _form-rooms.php
<?php
use yii\helpers\Html;
use wbraganca\dynamicform\DynamicFormWidget;
?>
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_inner',
'widgetBody' => '.container-rooms',
'widgetItem' => '.room-item',
'limit' => 4,
'min' => 1,
'insertButton' => '.add-room',
'deleteButton' => '.remove-room',
'model' => $modelsRoom[0],
'formId' => 'dynamic-form',
'formFields' => [
'description'
],
]); ?>
<table class="table table-bordered">
<thead>
<tr>
<th>Description</th>
<th class="text-center">
<button type="button" class="add-room btn btn-success btn-xs"><span class="glyphicon glyphicon-plus"></span></button>
</th>
</tr>
</thead>
<tbody class="container-rooms">
<?php foreach ($modelsRoom as $indexRoom => $modelRoom): ?>
<tr class="room-item">
<td class="vcenter">
<?php
// necessary for update action.
if (! $modelRoom->isNewRecord) {
echo Html::activeHiddenInput($modelRoom, "[{$indexHouse}][{$indexRoom}]id");
}
?>
<?= $form->field($modelRoom, "[{$indexHouse}][{$indexRoom}]description")->label(false)->textInput(['maxlength' => true]) ?>
</td>
<td class="text-center vcenter" style="width: 90px;">
<button type="button" class="remove-room btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus"></span></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
Source Code - Controller
<?php
namespace app\modules\yii2extensions\controllers;
use Yii;
use yii\helpers\ArrayHelper;
use yii\web\NotFoundHttpException;
use yii\web\Response;
use yii\widgets\ActiveForm;
use app\base\Model;
use app\base\Controller;
use app\modules\yii2extensions\models\House;
use app\modules\yii2extensions\models\Person;
use app\modules\yii2extensions\models\Room;
use app\modules\yii2extensions\models\query\PersonQuery;
/**
* DynamicformDemo3Controller implements the CRUD actions for Person model.
*/
class DynamicformDemo3Controller extends Controller
{
/**
* Lists all Person models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new PersonQuery();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Person model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
$model = $this->findModel($id);
$houses = $model->houses;
return $this->render('view', [
'model' => $model,
'houses' => $houses,
]);
}
/**
* Creates a new Person model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$modelPerson = new Person;
$modelsHouse = [new House];
$modelsRoom = [[new Room]];
if ($modelPerson->load(Yii::$app->request->post())) {
$modelsHouse = Model::createMultiple(House::classname());
Model::loadMultiple($modelsHouse, Yii::$app->request->post());
// validate person and houses models
$valid = $modelPerson->validate();
$valid = Model::validateMultiple($modelsHouse) && $valid;
if (isset($_POST['Room'][0][0])) {
foreach ($_POST['Room'] as $indexHouse => $rooms) {
foreach ($rooms as $indexRoom => $room) {
$data['Room'] = $room;
$modelRoom = new Room;
$modelRoom->load($data);
$modelsRoom[$indexHouse][$indexRoom] = $modelRoom;
$valid = $modelRoom->validate();
}
}
}
if ($valid) {
$transaction = Yii::$app->db->beginTransaction();
try {
if ($flag = $modelPerson->save(false)) {
foreach ($modelsHouse as $indexHouse => $modelHouse) {
if ($flag === false) {
break;
}
$modelHouse->person_id = $modelPerson->id;
if (!($flag = $modelHouse->save(false))) {
break;
}
if (isset($modelsRoom[$indexHouse]) && is_array($modelsRoom[$indexHouse])) {
foreach ($modelsRoom[$indexHouse] as $indexRoom => $modelRoom) {
$modelRoom->house_id = $modelHouse->id;
if (!($flag = $modelRoom->save(false))) {
break;
}
}
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $modelPerson->id]);
} else {
$transaction->rollBack();
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('create', [
'modelPerson' => $modelPerson,
'modelsHouse' => (empty($modelsHouse)) ? [new House] : $modelsHouse,
'modelsRoom' => (empty($modelsRoom)) ? [[new Room]] : $modelsRoom,
]);
}
/**
* Updates an existing Person model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$modelPerson = $this->findModel($id);
$modelsHouse = $modelPerson->houses;
$modelsRoom = [];
$oldRooms = [];
if (!empty($modelsHouse)) {
foreach ($modelsHouse as $indexHouse => $modelHouse) {
$rooms = $modelHouse->rooms;
$modelsRoom[$indexHouse] = $rooms;
$oldRooms = ArrayHelper::merge(ArrayHelper::index($rooms, 'id'), $oldRooms);
}
}
if ($modelPerson->load(Yii::$app->request->post())) {
// reset
$modelsRoom = [];
$oldHouseIDs = ArrayHelper::map($modelsHouse, 'id', 'id');
$modelsHouse = Model::createMultiple(House::classname(), $modelsHouse);
Model::loadMultiple($modelsHouse, Yii::$app->request->post());
$deletedHouseIDs = array_diff($oldHouseIDs, array_filter(ArrayHelper::map($modelsHouse, 'id', 'id')));
// validate person and houses models
$valid = $modelPerson->validate();
$valid = Model::validateMultiple($modelsHouse) && $valid;
$roomsIDs = [];
if (isset($_POST['Room'][0][0])) {
foreach ($_POST['Room'] as $indexHouse => $rooms) {
$roomsIDs = ArrayHelper::merge($roomsIDs, array_filter(ArrayHelper::getColumn($rooms, 'id')));
foreach ($rooms as $indexRoom => $room) {
$data['Room'] = $room;
$modelRoom = (isset($room['id']) && isset($oldRooms[$room['id']])) ? $oldRooms[$room['id']] : new Room;
$modelRoom->load($data);
$modelsRoom[$indexHouse][$indexRoom] = $modelRoom;
$valid = $modelRoom->validate();
}
}
}
$oldRoomsIDs = ArrayHelper::getColumn($oldRooms, 'id');
$deletedRoomsIDs = array_diff($oldRoomsIDs, $roomsIDs);
if ($valid) {
$transaction = Yii::$app->db->beginTransaction();
try {
if ($flag = $modelPerson->save(false)) {
if (! empty($deletedRoomsIDs)) {
Room::deleteAll(['id' => $deletedRoomsIDs]);
}
if (! empty($deletedHouseIDs)) {
House::deleteAll(['id' => $deletedHouseIDs]);
}
foreach ($modelsHouse as $indexHouse => $modelHouse) {
if ($flag === false) {
break;
}
$modelHouse->person_id = $modelPerson->id;
if (!($flag = $modelHouse->save(false))) {
break;
}
if (isset($modelsRoom[$indexHouse]) && is_array($modelsRoom[$indexHouse])) {
foreach ($modelsRoom[$indexHouse] as $indexRoom => $modelRoom) {
$modelRoom->house_id = $modelHouse->id;
if (!($flag = $modelRoom->save(false))) {
break;
}
}
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $modelPerson->id]);
} else {
$transaction->rollBack();
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('update', [
'modelPerson' => $modelPerson,
'modelsHouse' => (empty($modelsHouse)) ? [new House] : $modelsHouse,
'modelsRoom' => (empty($modelsRoom)) ? [[new Room]] : $modelsRoom
]);
}
/**
* Deletes an existing Person model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$model = $this->findModel($id);
$name = $model->first_name;
if ($model->delete()) {
Yii::$app->session->setFlash('success', 'Record <strong>"' . $name . '"</strong> deleted successfully.');
}
return $this->redirect(['index']);
}
/**
* Finds the Person model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Person the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Person::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
I've added a textinput field in my production form. The unitprice fills up when I select productname field drop down. But when I'm saving the data, I'm getting following error -
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'unitprice' cannot be null
The SQL being executed was: INSERT INTO `bottle` (`usedate`, `useqty`, `productname`, `bottlename`, `unitprice`) VALUES ('2016-04-21', '12', 'CEFO', 'Enter', NULL)
The last "NULL" is the value for unitprice.
actionCreate in productionController-
public function actionCreate()
{
$model = new Production();
$productname = new Productnames();
$bottle = new Bottle();
$bottlename = new Bottlename();
if ($model->load(Yii::$app->request->post()) && $productname->load(Yii::$app->request->post()))
{
$model->save();
//$bottle->attributes = $model->attributes;
$bottle->usedate = $model->productiondate;
$bottle->useqty = $model->prodqty;
$bottle->productname = $model->productname;
$bottle->bottlename = $productname->bottletype;
$bottle->unitprice = $bottlename->unitprice;
// $employee->emp_mobile = $model->emp_mobile;
$bottle->save();
return $this->redirect(['create']);
} else {
return $this->render('create', [
'model' => $model,
'bottle' => $bottle,
'productname' => $productname,
'bottlename' => $bottlename,
]);
}
}
Production _form
<?php
use yii\helpers\Html;
use yii\helpers\Url;
use yii\widgets\ActiveForm;
use yii\web\View;
use frontend\assets\XyzAsset;
use yii\helpers\ArrayHelper;
use dosamigos\datepicker\DatePicker;
use kartik\select2\Select2;
use frontend\modules\production\models\Productbatch;
use frontend\modules\production\models\Productnames;
use kartik\depdrop\DepDrop;
use yii\helpers\Json;
use frontend\modules\production\models\Bottlename;
//XyzAsset::register($this);
/* #var $this yii\web\View */
/* #var $model frontend\modules\production\models\Production */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="production-form">
<?php $form = ActiveForm::begin(); ?>
<!--<?= Html::a('Select Product', ['/production/productbatch/index'], ['class'=>'btn btn-primary']) ?> -->
<?= $form->field($model, 'productiondate')->widget(
DatePicker::className(), [
// inline too, not bad
'inline' => false,
// modify template for custom rendering
//'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
<!-- echo CHtml::button("(+)",array('title'=>"Select Product",'onclick'=>'js:selectproductforproduction();')); -->
<?= $form->field($model, 'productname')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Productnames::find()->all(),'productnames_productname','productnames_productname'),
'language' => 'en',
'options' => ['placeholder' => 'Select Product Name', 'id' => 'catid'],
'pluginOptions' => [
'allowClear' => true
],
]); ?>
<?= $form->field($model, 'batchno')->widget(DepDrop::classname(), [
'options'=>['id'=>'subcat-id'],
'pluginOptions'=>[
'depends'=>['catid'],
'placeholder'=>'Select BatchNo',
'url'=>Url::to(['/production/productbatch/subcat'])
]
]); ?>
<?= $form->field($model, 'prodqty')->textInput() ?>
<?= $form->field($productname, 'bottletype')->textInput() ?>
<?= $form->field($bottlename, 'unitprice')->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>
<?php
$script = <<< JS
$('#catid').change(function(){
var catid = $(this).val();
$.get('index.php?r=production/productnames/get-for-production',{ catid : catid }, function(data){
//alert(data);
var data = $.parseJSON(data);
$('#productnames-bottletype').attr('value',data.bottletype);
$('#bottlename-unitprice').attr('value',data.bottletype0.unitprice);
});
});
JS;
$this->registerJs($script);
?>
The action to get the data array
public function actionGetForProduction($catid)
{
$bottle = Productnames::find()->with('bottletype0')->where(['productnames_productname'=>$catid])->asArray()->one();
//$bottle -> select(['productnames.productnames_productname','productnames.bottletype','bottlename.unitprice'])->from('Productnames')->leftJoin('bottlename','productnames.bottletype = bottlename.bottlename')->where(['productnames_productname'=>$catid])->limit(1);
echo Json::encode($bottle);
This code works fine except the last unitprice. Please help.
You fotgot to add $bottlename->load(Yii::$app->request->post()) in if condition. So add like as,
if ($model->load(Yii::$app->request->post()) && $productname->load(Yii::$app->request->post()) && $bottlename->load(Yii::$app->request->post())) {
.......
}