Yii2 wbraganca-dynamicform updation using yii2-relation-trait not deleting items - yii2

Based on the https://github.com/wbraganca/yii2-dynamicform/wiki/Dynamic-Forms-With-Yii2-relation-trait-(VERY-EASY), I am trying to implement dynamic forms.Create is working perfect, but in Update form, if I delete any dynamic form element, it is not getting deleted, but If I add in the Update action, it is getting saved.
This is my Update code
public function actionUpdate($id)
{
$modelAlumni = $this->findModel($id);
$modelsJob = $modelAlumni->jobs;
if ($modelAlumni->loadAll(Yii::$app->request->post()) && $modelAlumni->saveAll()) {
return $this->redirect(['view', 'id' => $modelAlumni->id]);
} else {
return $this->render('update', [
'modelAlumni' => $modelAlumni,
'modelsJob' => (empty($modelsJob)) ? [new Job] : $modelsJob
]);
}
}
Why is it not deleting?
This is my Alumni model
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "alumni".
*
* #property integer $id
* #property string $name
* #property integer $gender
* #property integer $contact_number
* #property string $year_graduated
* #property string $qualification
* #property integer $department_id
* #property integer $specialization
* #property string $email
*
* #property Job[] $jobs
*/
class Alumni extends \yii\db\ActiveRecord
{
use \mootensai\relation\RelationTrait;
public $organization;
public $designation;
public $location;
public $current_status;
public $joining_date;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'alumni';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['name', 'gender', 'contact_number', 'year_graduated', 'qualification', 'department_id', 'specialization', 'email'], 'required'],
[['name', 'organization', 'designation', 'location'], 'string'],
[['gender', 'contact_number', 'department_id', 'specialization'], 'integer'],
[['year_graduated'], 'safe'],
[['qualification', 'email'], 'string', 'max' => 500],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'name' => Yii::t('app', 'Name'),
'gender' => Yii::t('app', 'Gender'),
'contact_number' => Yii::t('app', 'Contact Number'),
'year_graduated' => Yii::t('app', 'Year Graduated'),
'qualification' => Yii::t('app', 'Qualification'),
'department_id' => Yii::t('app', 'Department ID'),
'specialization' => Yii::t('app', 'Specialization'),
'email' => Yii::t('app', 'Email'),
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getJobs()
{
return $this->hasMany(Job::className(), ['alumni_id' => 'id']);
}
}
Here is my Job Model
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "job".
*
* #property integer $job_id
* #property string $organization
* #property string $current_status
* #property string $designation
* #property string $joining_date
* #property string $location
* #property integer $alumni_id
*
* #property Alumni $alumni
*/
class Job extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'job';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['organization', 'current_status', 'designation', 'joining_date', 'location', 'alumni_id'], 'required'],
[['organization'], 'string'],
[['joining_date'], 'safe'],
[['alumni_id'], 'integer'],
[['current_status', 'designation'], 'string', 'max' => 300],
[['location'], 'string', 'max' => 255],
[['alumni_id'], 'exist', 'skipOnError' => true, 'targetClass' => Alumni::className(), 'targetAttribute' => ['alumni_id' => 'id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'job_id' => Yii::t('app', 'Job ID'),
'organization' => Yii::t('app', 'Organization'),
'current_status' => Yii::t('app', 'Current Status'),
'designation' => Yii::t('app', 'Designation'),
'joining_date' => Yii::t('app', 'Joining Date'),
'location' => Yii::t('app', 'Location'),
'alumni_id' => Yii::t('app', 'Alumni ID'),
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getAlumni()
{
return $this->hasOne(Alumni::className(), ['id' => 'alumni_id']);
}
}

There is example, look at actionUpdate
https://github.com/wbraganca/yii2-dynamicform
first find All nested models ids that not in cuurrent POST request
$oldIDs = ArrayHelper::map($modelsAddress, 'id', 'id');
$modelsAddress = Model::createMultiple(Address::classname(), $modelsAddress);
Model::loadMultiple($modelsAddress, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsAddress, 'id', 'id')));
then in transaction after save mainModel delete it:
if (! empty($deletedIDs))
{
Address::deleteAll(['id' => $deletedIDs]);
}
This is example, you have to implement for your own solution.
I think there is bug in relation-triat:
https://github.com/mootensai/yii2-relation-trait/issues/27
So above is the best solution

Related

Acess belongsTo by where

I got this code:
public function Locate($name){
$locate= Products::where('name', 'like', "$name%") ->get();
return response()->json($locate, 200);
}
I want to access belongsTo by this $name and put it in json
Here is my model:
class Products extends Model
{
protected $fillable = ['name', 'code', 'price'];
protected $hidden = ['id'];
public function Group()
{
return $this->belongsTo('App\pGroup', 'product_id', 'id');
}
}
If you want to get a relationship :
$locate= Products::where('name', 'like', "$name%")->with('group')->get();

Records are not getting saved in database table in yii2

I have taluka model where we select district and enter as many talukas.
But the records are not getting saved.
public function actionCreate()
{
$model = new Taluka();
if ($model->load(Yii::$app->request->post()) ) {
$talukaslist = $model->talukas;
if(is_array($talukaslist))
{
foreach($talukaslist as $taluka)
{
if($taluka ==null)
{
return $this->render('create', [
'model' => $model,
]);
}
else
if($taluka!=null)
{
$talukaRecord = new Taluka();
$talukaRecord->DistrictId = $model->DistrictId;
$talukaRecord->Taluka = $taluka;
$talukaRecord->save();
}
}
}
return $this->redirect(['index']);
}
else {
return $this->render('create', [
'model' => $model,
]);
}
}
If I use $talukaRecord->save(false), then the records are getting saved even if the validation fails.
Model:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "taluka".
*
* #property integer $TalukaId
* #property integer $DistrictId
* #property string $Taluka
*
* #property Area[] $areas
* #property Colony[] $colonies
* #property Colonydemographic[] $colonydemographics
* #property District $district
* #property Village[] $villages
* #property Villagedemographic[] $villagedemographics
*/
class Taluka extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public $talukas=[];
public static function tableName()
{
return 'taluka';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['DistrictId', 'Taluka'], 'required'],
[['DistrictId'], 'integer'],
[['talukas'], 'required'],
[['Taluka'], 'string', 'max' => 100],
[['DistrictId'], 'exist', 'skipOnError' => true, 'targetClass' => District::className(), 'targetAttribute' => ['DistrictId' => 'DistrictId']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'TalukaId' => 'Taluka ID',
'DistrictId' => 'District',
'talukas' => 'Taluka',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getAreas()
{
return $this->hasMany(Area::className(), ['TalukaId' => 'TalukaId']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getColonies()
{
return $this->hasMany(Colony::className(), ['TalukaId' => 'TalukaId']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getColonydemographics()
{
return $this->hasMany(Colonydemographic::className(), ['TalukaId' => 'TalukaId']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getDistrict()
{
return $this->hasOne(District::className(), ['DistrictId' => 'DistrictId']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getVillages()
{
return $this->hasMany(Village::className(), ['TalukaId' => 'TalukaId']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getVillagedemographics()
{
return $this->hasMany(Villagedemographic::className(), ['TalukaId' => 'TalukaId']);
}
}
Please try below code
public function actionCreate()
{
$model = new Taluka();
if ($model->load(Yii::$app->request->post()) ) {
$talukaslist = $model->talukas;
if(isset($talukaslist) && && $talukaslist!=array())
{
foreach($talukaslist as $taluka)
{
if(isset($taluka) && $taluka ==null)
{
return $this->render('create', [
'model' => $model,
]);
}
else
if(isset($taluka) && $taluka!=null)
{
$talukaRecord = new Taluka();
$talukaRecord->DistrictId = $model->DistrictId;
$talukaRecord->Taluka = $taluka;
if($talukaRecord->save())
{}
else
{
echo "<pre>";
print_r($talukaRecord->getErrors());die;
}
}
}
}
return $this->redirect(['index']);
}
else {
return $this->render('create', [
'model' => $model,
]);
}
}

Expected argument of type "biblioBundle\Entity\Profil", "integer" given

PersonneController.php
<?php
namespace biblioBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use biblioBundle\Entity\Personne;
use biblioBundle\Form\PersonneType;
/**
* Personne controller.
*
*/
class PersonneController extends Controller
{
/**
* Lists all Personne entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$personnes = $em->getRepository('biblioBundle:Personne')->findAll();
return $this->render('personne/index.html.twig', array(
'personnes' => $personnes,
));
}
/**
* Creates a new Personne entity.
*
*/
public function newAction(Request $request)
{
//$em = $this->getDoctrine()->getManager();
//$prf = $em->getRepository('biblioBundle:Profil')->findAll();
$personne = new Personne();
$form = $this->createForm(PersonneType::class, $personne);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($personne);
$em->flush();
return $this->redirectToRoute('personne_show', array('id' => $personne->getIdpersonne()));
}
return $this->render('personne/new.html.twig', array(
'personne' => $personne,
'form' => $form->createView(),
));
}
PersonneType.php
<?php
namespace biblioBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use biblioBundle\Entity\Profil;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
class PersonneType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nom')
->add('prenom')
->add('datenaiss', 'date')
->add('adresse')
->add('photo1')
->add('sexe',ChoiceType::class,array(
'choices' => array(
'H' => 'Homme',
'F' => 'Femme')))
->add('idProfil',IntegerType::class);
}
/* public function getName()
{
return 'name';
}*/
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'biblioBundle\Entity\Personne'
));
}
}
Personne.php
<?php
namespace biblioBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Personne
*
* #ORM\Table(name="personne", indexes= {#ORM\Index(name="FK_Appartenir2", columns={"idProfil"})})
* #ORM\Entity
*/
class Personne
{
/**
* #var string
*
* #ORM\Column(name="Nom", type="string", length=20, nullable=false)
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="Prenom", type="string", length=20, nullable=false)
*/
private $prenom;
/**
* #var \DateTime
*
* #ORM\Column(name="DateNaiss", type="date", nullable=false)
*/
private $datenaiss;
/**
* #var string
*
* #ORM\Column(name="Adresse", type="string", length=100, nullable=true)
*/
private $adresse;
/**
* #var string
*
* #ORM\Column(name="Photo1", type="string", length=255, nullable=true)
*/
private $photo1;
/**
* #var string
*
* #ORM\Column(name="Sexe", type="string", length=1, nullable=false)
*/
private $sexe;
/**
* #var integer
*
* #ORM\Column(name="idPersonne", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idpersonne;
/**
* #var \biblioBundle\Entity\Profil
*
* #ORM\ManyToOne(targetEntity="biblioBundle\Entity\Profil")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="idProfil", referencedColumnName="idProfil")
* })
*/
private $idprofil;
/**
* Set nom
*
* #param string $nom
* #return Personne
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set prenom
*
* #param string $prenom
* #return Personne
*/
public function setPrenom($prenom)
{
$this->prenom = $prenom;
return $this;
}
/**
* Get prenom
*
* #return string
*/
public function getPrenom()
{
return $this->prenom;
}
/**
* Set datenaiss
*
* #param \DateTime $datenaiss
* #return Personne
*/
public function setDatenaiss($datenaiss)
{
$this->datenaiss = $datenaiss;
return $this;
}
/**
* Get datenaiss
*
* #return \DateTime
*/
public function getDatenaiss()
{
return $this->datenaiss;
}
/**
* Set adresse
*
* #param string $adresse
* #return Personne
*/
public function setAdresse($adresse)
{
$this->adresse = $adresse;
return $this;
}
/**
* Get adresse
*
* #return string
*/
public function getAdresse()
{
return $this->adresse;
}
/**
* Set photo1
*
* #param string $photo1
* #return Personne
*/
public function setPhoto1($photo1)
{
$this->photo1 = $photo1;
return $this;
}
/**
* Get photo1
*
* #return string
*/
public function getPhoto1()
{
return $this->photo1;
}
/**
* Set sexe
*
* #param string $sexe
* #return Personne
*/
public function setSexe($sexe)
{
$this->sexe = $sexe;
return $this;
}
/**
* Get sexe
*
* #return string
*/
public function getSexe()
{
return $this->sexe;
}
/**
* Get idpersonne
*
* #return integer
*/
public function getIdpersonne()
{
return $this->idpersonne;
}
/**
* Set idprofil
*
* #param \biblioBundle\Entity\Profil $idprofil
* #return Personne
*/
public function setIdprofil(\biblioBundle\Entity\Profil $idprofil = null)
{
$this->idprofil = $idprofil;
return $this;
}
/**
* Get idprofil
*
* #return \biblioBundle\Entity\Profil
*/
public function getIdprofil()
{
return $this->idprofil;
}
}
Every time I try to run the code I get:
{Expected argument of type "biblioBundle\Entity\Profil", "integer" given }
Please I need help.
In your PersonneType class you have line:
->add('idProfil',IntegerType::class);
when in Personne class you have:
public function setIdprofil(\biblioBundle\Entity\Profil $idprofil = null)
{
$this->idprofil = $idprofil;
return $this;
}
You need to have Profil instance instead of integer (defined in form). How to solve this?
Replace IntegerType class to EntityType.
Add data transformer to form and transform integer to Profil and vice versa.
Replace argument $idprofil with integer type instead of Profil.

YII2 Associations examples or via() or viaTable() example

HI All,
This example will help you how to get products details of customer using restful API call,
your API call should like this :
http://127.0.0.1:8080/api/web/customer?expand=orders,orderItems,products
class Customer extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'customer';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['ID', 'Name'], 'required'],
[['ID'], 'integer'],
[['Name'], 'string'],
[['PhoneNo'], 'string', 'max' => 45]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'ID' => 'ID',
'Name' => 'Name',
'PhoneNo' => 'Phone No',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getOrders()
{
return $this->hasMany(Order::className(), ['customer_id' => 'ID']);
}
public function getOrderItems()
{
return $this->hasMany(Orderitem::className(),['Order_id' => 'ID' ])
->via('orders');
;
}
public function getProducts()
{
return $this->hasMany( Product::className() , ['ID' => 'Product_ID' ] )
->via('orderItems') ;
}
/**
* #inheritdoc
* #return CustomerQuery the active query used by this AR class.
*/
public static function find()
{
return new CustomerQuery(get_called_class());
}
/**
* #info: call : http://127.0.0.1:8080/api/web/customer?expand=orders for get customer and his orders also;
* #return type
*/
public function extraFields()
{
return ['orders','orderItems','products'];
}
}

Yii2 include assets after code generated by widget

How to include my .js files after javascript code generated by Datepicker widget in view file.
echo DatePicker::widget([
'name' => 'datepicker--2',
'id' => 'datepicker--2',
'clientOptions' => [
'showOtherMonths' => true,
'maxDate' => '+ 0d',
'showOtherMonths' => true,
'selectOtherMonths' => true,
]
]);
My asset bundle:
namespace app\assets;
use yii\web\AssetBundle;
class ChartsAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $js = [
'js/charts.js',
'js/charts-init.js',
];
public $depends = [
'yii\web\YiiAsset',
'yii\jui\JuiAsset',
'yii\web\JqueryAsset',
];
}
What I'm getting on my page source:
...
<script src="/new/js/charts.js"></script>
<script src="/new/js/charts-init.js"></script>
<script type="text/javascript">jQuery(document).ready(function () {
$('#datepicker--2').datepicker($.extend({}, {"showOtherMonths":true,"maxDate":"+ 0d","selectOtherMonths":true,"dateFormat":"M d, yy"}));
});</script></body>
</html>
With yii2, you have options to define the position (HEAD, BEGIN OR END) of the client scripts with in the the document. This can be achieved by doing something like this
public $jsOptions = [
'position' => \yii\web\View::POS_HEAD
];
Or Using This.
Create BaseAssets like this:
namespace app\assets;
class BaseAsset extends AssetBundle
{
public $sourcePath = '#resources'; // #app/resources
public $css = [];
public $js = [];
public $depends = [
'yii\web\YiiAsset',
'yii\jui\JuiAsset',
'yii\web\JqueryAsset',
];
public $jsOptions = [ 'position' => \yii\web\View::POS_HEAD ];
}
And your Assets:
namespace app\assets;
use yii\web\AssetBundle;
class ChartsAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $js = [
'js/charts.js',
'js/charts-init.js',
];
public $depends = [
'app\assets\BaseAssets',
];
public $jsOptions = [ 'position' => \yii\web\View::POS_END ];
}