I have a project where I have a procedures, categories and subcategories table,
Sub-category poced from a foreign key to category
Procedure has a foreign key to category and to subcategory
In my controller / setupListOperation, I added 2 filters that I would like to put in relation, see that the subcategories of the category select as a filter.
But I do not see how to make the link between the two select2_ajax.
// Filtre sur la catégorie
CRUD::addFilter([
'name' => 'filtre_categorie',
'type' => 'select2',
'label' => 'Filtre de catégorie',
'placeholder' => 'Sélectionner une catégorie',
'minimum_input_length' => 0,
],
function () { return \App\Models\Categorie::all()->keyBy('id')->pluck('name', 'id')->toArray();
}, function ($value) { // if the filter is active
$this->crud->addClause('where', 'categorie_id', $value);
});
// Filtre sur la sous catégorie
CRUD::addFilter([
'name' => 'filtre_souscategorie',
'type' => 'select2_ajax',
'label' => 'Filtre de sous-catégorie',
'placeholder' => 'Sélectionner une sous-catégorie',
'minimum_input_length' => 0,
],
url('admin/procedure/ajax-souscategory-options'), // the ajax route
function($value) { // if the filter is active
$this->crud->addClause('where', 'souscategorie_id', $value);
});
I found a solution by doing so:
My Field :
// Filtre sur nom
CRUD::addFilter([
'type' => 'text',
'name' => 'nom_filter',
'label' => 'Recherhe par nom de procédure'
],
false,
function($value) { // if the filter is active
$this->crud->addClause('where', 'name', 'LIKE', "%$value%");
});
// Filtre sur la catégorie
CRUD::addFilter([
'name' => 'filtre_categorie',
'type' => 'select2',
'label' => 'Filtre de catégorie',
'placeholder' => 'Sélectionner une catégorie',
'minimum_input_length' => 0,
],
function () { return \App\Models\Categorie::all()->keyBy('id')->pluck('name', 'id')->toArray();
}, function ($value) { // if the filter is active
$this->crud->addClause('where', 'categorie_id', $value);
});
My Class :
public function souscategoryFilterOptions(Request $request) {
$term = $request->input('term');
$options = \App\Models\Souscategorie::query();
$str = $_SERVER['HTTP_REFERER'];
$qs = parse_url($str, PHP_URL_QUERY);
if(!empty($qs)){
parse_str($qs, $output);
$resultsFilter = $options->where('categorie_id', $output['filtre_categorie'])->get()->pluck('name', 'id');
}
if ($term) {
$resultsFilter = $options->where('name', 'LIKE', '%'.$term.'%')->paginate(10);
} else {
$resultsFilter = $options->paginate(10);
}
return $resultsFilter;
}
Related
I need some help inserting into database invoice and products from the same form. I have had so many errors.
Invoice database:
Schema::create('invoices', function (Blueprint $table) {
$table->increments('id');
$table->integer('invoice_no');
$table->date('invoice_date');
$table->date('due_date');
$table->string('title');
$table->string('client');
$table->string('client_address');
$table->decimal('subtotal');
$table->decimal('grandtotal');
$table->timestamps();
});
Product database:
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('invoice_id')->unsigned();
$table->string('name');
$table->string('qty');
$table->string('price');
$table->string('total');
$table->timestamps();
});
Invoice model:
protected $fillable = [
'client',
'client_address',
'title',
'invoice_no',
'invoice_date',
'due_date',
'discount',
'subtotal',
'grandtotal'
];
Product model:
public function products() {
return $this->hasMany('App\Product', 'invoice_id');
}
protected $casts = [
'name' => 'array',
'price' => 'array',
'qty' => 'array',
'total' => 'array'
];
protected $fillable = ['invoice_id','price','qty','total','name'];
public function invoice() {
return $this->belongsTo('App\Invoice');
}
Invoice controller:
$invoice = new Invoice();
$invoice->invoice_no = $request->invoice_no;
$invoice->client = $request->client;
$invoice->title = $request->title;
$invoice->client_address = $request->client_address;
$invoice->invoice_date = $request->invoice_date;
$invoice->due_date = $request->due_date;
$invoice->subtotal = $request->subtotal;
$invoice->grandtotal = $request->grandtotal;
$input = $request->all();
$product = new Product();
$product->name = $input['name'];
$product->price = $input['price'];
$product->qty = $input['qty'];
$product->total = $input['total'];
$invoice->save();
$product->invoice_id = $invoice->id;
$invoice->products()->save($product);
You have an invoice that has many products. So, first create your invoice
$invoice = \Invoice::create([
'invoice_no' => $request->invoice_no,
'client' => $request->client,
'title' => $request->title,
'client_address' => $request->client_address,
'invoice_date' => $request->invoice_date,
'due_date' => $request->due_date,
'subtotal' => $request->subtotal,
'grandtotal' => $request->grandtotal
]);
And then, add its products
$product = $invoice->products()->create([
'name' => $request->name,
'price' => $request->price,
'qty' => $request->qty,
'total' => $request->total
])
If you have more than one product, put the product creation in a foreach loop.
How you manage the insertion of your products, depends on your form structure. In the continue, I will give you an example of the whole process.
I assume that this is your form:
<form>
<div class="product">
<input name="products[0][name]" >
<input name="products[0][price]" >
<input name="products[0][qty]" >
<input name="products[0][total]" >
</div>
<div class="product">
<input name="products[1][name]" >
<input name="products[1][price]" >
<input name="products[1][qty]" >
<input name="products[1][total]" >
</div>
<div class="product">
<input name="products[2][name]" >
<input name="products[2][price]" >
<input name="products[2][qty]" >
<input name="products[2][total]" >
</div>
<button type="submit" >Submit</button>
</form>
After submitting the form, you will have an array of your products:
$request->products
returns
[
[
'name' => 'some name',
'price' => '10',
'qty' => '2',
'total' => '20',
], [
'name' => 'some name',
'price' => '10',
'qty' => '2',
'total' => '20',
], [
'name' => 'some name',
'price' => '10',
'qty' => '2',
'total' => '20',
],
]
Now you can insert them in the database like below:
foreach($request->products as $product) {
$invoice->products()->create([
'name' => $product['name'],
'price' => $product['price'],
'qty' => $product['qty'],
'total' => $product['total']
]);
}
OR
foreach($request->products as $product) {
$invoice->products()->create($product);
}
I have a view like this:
// snippet of view
<td><input class="form-field" type="text" id="entity" name="name" data="{{$entity->id}}" value="{{$entity->name}}" onkeyup="validation(this.value);" onblur="updateEntity(this.value,this.name,this.id,{{$entity->id}})"></td>
<td><input class="form-field" type="text" id="entity" name="type" value="{{$entity->type}}" onkeyup="validation(this.value);" onblur="updateEntity(this.value,this.name,this.id,{{$entity->id}})"></td>
Which has an ajax:
function updateEntity(value, name, data, id) {
$.ajax({
url: '/entityadmin/' + value + '/' + name + '/' + data + '/' + id,
method: 'POST',
dataType: 'json',
success: function(save) {
$('.messages').append('<div class="alert alert-success">Type Updated!<div>');
setTimeout(function() {
$(".alert").fadeTo(2000, 500).slideUp(500, function(){
$(".alert").slideUp(500);
});
}, 4000);
},
error: function(data) {
console.log(data);
$('.messages').append('<div class="alert alert-danger">Error, please try again!<div>');
setTimeout(function() {
$(".alert").fadeTo(2000, 500).slideUp(500, function(){
$(".alert").slideUp(500);
});
}, 4000);
},
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
}
Controller:
public function entityUpdate($value, $name, $data, $id, EntityRequestUpdate $request) {
$request->$name = $value; //like this?
if($data == "entity") {
$save = Entity::find($id);
}else{
$save = User::find($id);
}
$save->$name = $value;
$save->save();
return response()->json(['results' => $save]);
}
and request:
public function rules()
{
return [
'startdate' => 'required|date',
'endate' => 'nullable|date',
'startime' => 'required|time',
'endtime' => 'required|time',
'title' => 'required',
'type' => 'required',
'description' => 'required',
'frequency' => 'required',
'interval' => 'nullable|numeric',
'monthday' => 'nullable|numeric|min:1|max:3',
'weekday' => 'nullable|alpha|max:3',
'month' => 'nullable|numeric',
'until' => 'nullable|date',
'tags' => 'nullable',
'img' => 'nullable|file|image',
];
}
The thing is it only has to validate one field because one field is being changed each time, how can I use this validation to validate the incoming variable and return errors to ajax with the message on the error if there is any?
You can manually create a validator to validate this one field like so:
$validator = Validator::make(
[ 'name' => $value ],
collect($this->rules())->only([$name])->all()
);
This validator will take the name validator from the defined rules and check that against the first array of values.
I have this error message when I submit form.
Notice: Undefined index: title in
C:\xampp\htdocs\ameyaw\module\BusinessGhana\src\Service\AutosManager.php
on line 38
Notice: Undefined index: description in
C:\xampp\htdocs\ameyaw\module\BusinessGhana\src\Service\AutosManager.php
on line 39
Notice: Undefined index: featured in
C:\xampp\htdocs\ameyaw\module\BusinessGhana\src\Service\AutosManager.php
on line 58
Message:
An exception occurred while executing 'INSERT INTO auto (title,
description, featured, date_created) VALUES (?, ?, ?, ?)' with params
[null, null, null, "2017-06-15 05:04:44"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'title'
cannot be null
this is my form and fieldset
use Zend\Form\Fieldset;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use BusinessGhana\Entity\Autos;
class AddFieldset extends Fieldset
{
protected $objectManager;
public function init()
{
$this->add([
'type' => 'text',
'name' => 'title',
'attributes' => [
'id' => 'autoTitle'
],
'options' => [
'label' => 'Title',
'display_empty_item' => true,
'empty_item_label' => 'Maximum of 60 characters',
],
]);
$this->add([
'type' => 'textarea',
'name' => 'description',
'attributes' => [
'id' => 'autoDescription'
],
'options' => [
'label' => 'Description',
'display_empty_item' => true,
'empty_item_label' => 'description',
],
]);
$this->add([
'type' => 'radio',
'name' => 'featured',
'attributes' => [
'id' => 'autoFeatured'
],
'options' => array(
'label' => 'Featured',
'value_options' => array(
array('value' => '0',
'label' => 'No',
'selected' => true,
'label_attributes' => array(
'class' => 'col-sm-2 btn btn-default',
),
),
array(
'value' => '1',
'label' => 'Yes',
'label_attributes' => array(
'class' => 'col-sm-2 btn btn-danger',
),
),
),
'column-size' => 'sm-12',
'label_attributes' => array(
'class' => 'col-sm-2',
),
),
]);
}
}
use Zend\Form\Form;
//use Zend\InputFilter\InputFilter;
class AddForm extends Form
{
public function init()
{
$this->add([
'name' => 'dependentForm',
'type' => AddFieldset::class,
]);
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Submit',
],
]);
}
}
This is my controller action
public function addAction()
{
// Create the form.
$form = new PostForm();
if ($this->getRequest()->isPost()) {
// Get POST data.
$data = $this->params()->fromPost();
// Fill form with data.
$form->setData($data);
if ($form->isValid()) {
// Get validated form data.
$data = $form->getData();
$this->AutosManager->addNewAutos($data);
return $this->redirect()->toRoute('retrieve');
}
}
return new ViewModel([
'form' => $form
]);
}
I know hydration can solve this problem but I don't know how to use it yet.
thanks for any help.
this is my autosManager
class AutosManager
{
/**
* Entity manager.
* #var Doctrine\ORM\EntityManager;
*/
private $entityManager;
/**
* Constructor.
*/
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
}
public function addNewAutos($data)
{
$autos = new Autos();
$autos->setTitle($data['title']);
$autos->setDescription($data['description']);
$autos->setFeatured($data['featured']);
$currentDate = date('Y-m-d H:i:s');
$autos->setDateCreated($currentDate);
$this->entityManager->persist($autos);
$this->entityManager->flush();
}
}
i can retrieve data from database.
This is where i render my forms:
$form = $this->form;
$fieldset = $form->get('dependentForm');
$title = $fieldset->get('title');
$title->setAttribute('class', 'form-control');
$title->setAttribute('placeholder', 'Maximum of 60 characters');
$title->setAttribute('id', 'autoTitle');
$description = $fieldset->get('description');
$description->setAttribute('class', 'form-control');
$description->setAttribute('placeholder', 'Description here...');
$description->setAttribute('id', 'autoDescription');
$featured = $fieldset->get('featured');
$featured->setAttribute('id', 'autoRadio');
$form->get('submit')->setAttributes(['class'=>'btn btn-primary']);
$form->prepare();
echo $this->form()->openTag($form);
?>
<fieldset>
<div class="form-group">
<?= $this->formLabel($title) ?>
<?= $this->formElement($title) ?>
<?= $this->formElementErrors()->render($title,['class'=>'help-block'])?>
</div>
<div class="form-group">
<?= $this->formLabel($description) ?>
<?= $this->formElement($description) ?>
<?=$this->formElementErrors()->render($description,
['class'=>'help-block'])?>
</div>
<div class="form-group">
<?= $this->formLabel($featured) ?>
<?= $this->formElement($featured) ?>
<?= $this->formElementErrors()->render($featured,
['class' =>'help-block']) ?>
</div>
</div></div><div class="row">
<div class="col-md-4">
</fieldset>
<?= $this->formElement($form->get('submit')); ?>
In your function addNewAutos($data) : your $data variable don't have title, description and featured fields. So php consider these as null, and your $this->entityManager->flush() will try to write null values in database, but you have a constraint that at least title must not be null.
So check your $data array contains the title, description and featured fields before to initiate your Auto object...
How can I do: I have 2 multi-select fields Select2, the first field for Branches, second for Workers.
When I choose branches, in second field I need to show Workers, who work in this branches.
View file
<label><?= $model->getAttributeLabel('branch') ?></label>
<?php echo Select2::widget([
'name' => 'branch',
'id' => 'branches',
'theme' =>Select2::THEME_BOOTSTRAP,
'value' => '',
'data' => $branchList,
'options' => [
'placeholder' => Yii::t('app', 'Choose branch'),
'multiple' => true,
],
'pluginOptions' => [
'tags' => true,
'allowClear' => true,
],]);?>
<label><?= $model->getAttributeLabel('Workers') ?></label>
<?php echo Select2::widget([
'name' => 'worker',
'id' => 'workers',
'theme' =>Select2::THEME_BOOTSTRAP,
'value' => '',
'data' => [],
'options' => [
'placeholder' => Yii::t('app', 'Choose workers'),
'multiple' => true,
],
'pluginOptions' => [
'tags' => true,
'allowClear' => true,
],]);
?>
JS
$("#branches").change(function(){
change();
});
function change() {
var selectValue = $("#branches").val();
$("#workers").empty();
$.post( "'.Yii::$app->urlManager->createUrl('constructor/lists?id=').'"+selectValue,
function(data){
$("#workers").html(data);
}
);
};
ConstructorController
public function actionLists($id)
{
if ($id != null) {
$ids = explode(",", $id);
foreach ($ids as $id_branch) {
$workers = Report::getWorkers($id_branch);
if (count($workers) > 0) {
foreach ($workers as $worker) {
echo "<option value='" . $worker . "'>" . $worker . "</option>";
}
} else {
echo "'<option>-</option>'";
}
}
}
}
I have a field gentel_id with the following validation rules in my model Contrat:
public $validate = array(
'gentel_id' => array(
'numeric' => array(
'rule' => 'numeric',
'required' => true,
'allowEmpty' => false,
'message' => 'Veuillez entrer un identifiant GENTEL ou mettre la valeur 0000000000',
),
),
);
In my controller:
public function add($id = null) {
if ($this->request->is('post')) {
$this->Contrat->create();
if ($this->Contrat->save($this->request->data)) {
$this->Session->setFlash(__('Le Contrat a été ajouté'));
$this->redirect(array('action' => 'edit', $this->Contrat->getInsertID() ));
} else {
debug($this->Contrat->validationErrors);
$this->Session->setFlash(__('Le Contrat ne peut être ajouté'));
}
$this->set('id',$id);
...
}
In my form:
<?php echo $this->Form->create('Contrat');?>
<?php
if (empty($id)){
echo $this->Form->input('client_id',array('empty' => "Client non défini",'default' => $id, 'onchange'=>"window.location.href= '/contrats/add/'+this.form.ContratClientId.options[this.form.ContratClientId.selectedIndex].value"));
}else{
echo "<span class=\"label\">".__('Client')."</span>".$this->Kaldom->link(h($clients[$id]),array('controller' => 'clients', 'action' => 'view',$id));
echo $this->Form->input('client_id', array('type' => 'hidden','value' => $id));
}
echo $this->Form->input('gentel_id',array('type'=>'text','label'=> 'Gentel ID'));
?>
<?php echo $this->Form->end(__('Créer'));?>
When I try to save my form with "gentel_id" empty, the save is correctly not done and a debug ($this->Contrat->validationErrors) give me this:
Array
(
[gentel_id] => Array
(
[0] => Veuillez entrer un identifiant GENTEL ou mettre la valeur 0000000000
)
)
But the error messsage is not displayed in my form.
Note that it is an add function but I have passed a parameter in the url like this:
.../contrats/add/3
Can you help me please?