Asking about codeigniter 3 form validation with callback.
Form validation - thats validating an array of data - in this case a group of products - and one rule has a callback. Like:
$this->form_validation->set_rules('productid[]', 'Product ID', 'required');
$this->form_validation->set_rules('productsku[]', 'Product SKU', 'callback_sku_check');
and then the callback goes to the method: sku_check($str)
All that works fine, churns through and checks an array of product skus no problem. Now is there a way to pass the correct Product ID from the array to the callback method? So i could have
sku_check($str,$productid)
where the product id matches the specific sku in the array?
Related
In my Laravel 5.1 app, I have classes Page (models a webpage) and Media (models an image). A Page contains a collection of Media objects and this relationship is maintained in a "media_page" pivot table. The pivot table has columns for page_id, media_id and sort_order.
A utility form on the site allows an Admin to manually associate one or more Media items to a Page and specify the order in which the Media items render in the view. When the form submits, the Controller receives a sorted list of media ids. The association is saved in the Controller store() and update() methods as follows:
[STORE] $page->media()->attach($mediaIds);
[UPDATE] $page->media()->sync($mediaIds);
This works fine but doesn't allow me to save the sort_order specified in the mediaIds request param. As such, Media items are always returned to the view in the order in which they appear in the database, regardless of how the Admin manually ordered them. I know how to attach extra data for the pivot table when saving a single record, but don't know how to do this (or if it's even possible) when passing an array to attach() or sync(), as shown above.
The only ways I can see to do it are:
loop over the array, calling attach() once for each entry and passing along the current counter index as sort_order.
first detach() all associations and then pass mediaIds array to attach() or sync(). A side benefit would be that it eliminates the need for a sort_order column at all.
I'm hoping there is an easier solution that requires fewer trips to the database. Or am I just overthinking it and, in reality, doing the loop myself is really no different than letting Laravel do it further down the line when it receives the array?
[SOLUTION] I got it working by reshaping the array as follows. It explodes the comma-delimited 'mediaIds' request param and loops over the resulting array, assigning each media id as the key in the $mediaIds array, setting the sort_order value equal to the key's position within the array.
$rawMediaIds = explode(',', request('mediaIds'));
foreach($rawMediaIds as $mediaId) {
$mediaIds[$mediaId] = ['sort_order' => array_search($mediaId, $rawMediaIds)];
}
And then sorted by sort_order when retrieving the Page's associated media:
public function media() {
return $this->belongsToMany(Media::class)->orderBy('sort_order', 'asc');
}
You can add data to the pivot table while attaching or syncing, like so:
$mediaIds = [
1 => ['sort_order' => 'order_for_1'],
3 => ['sort_order' => 'order_for_3']
];
//[STORE]
$page->media()->attach($mediaIds;
//[UPDATE]
$page->media()->sync($mediaIds);
When using an ActiveRecord to retrieve models it's possible to select a few columns. For example:
Product::find()->select('product_id,name')->all();
There are more columns than product_id and name in the database, but this example returns an array filled with all models, having only the product_id and name attributes filled. This is expected of course because I've passed them into select().
Now when looping through the found models and calling $model->getAttributes() it returns an array of all model attributes and their values (null for the not-selected attributes), including all columns that were not selected in the query but are in the model's attributes() function.
Is there a way to call a function similar to getAttributes() but returning only the populated attributes that were selected in the query: product_id and name?
I know it's possible to pass in exclusions to getAttributes() but I'd rather have the populated attributes returned based on the values I've selected in the ActiveRecord query.
In your case you should be able to use fields() method:
$attributes = $model->getAttributes($model->fields());
Note that fields() does not guarantee this behavior if you change model after find - unsetting (unset($model->product_id)) or setting ($model->some_field = 'some value') attributes will affect result of fields().
I'm working with Code Igniter to validate a form. I would like a field to be optional, but if the user provides a value, it should have a minimum length.
As a rule, I have mentionned
min_length[500]
If I post my form with an empty value, it returns me an error regarding the size of the input being too short.
How can I meet my requirement?
Thank you,
Aurélien
You could set a condition on that specific field, like if the field is not empty :
$this->form_validation->set_rules('field_1', 'Field 1', 'required');
if (!empty($this->input->post('field_2')))
{
$this->form_validation->set_rules('field_2', 'Field 2', 'min_length[500]');
}
I have an input with an array of entities with an ID which must be unique
I've tried this:
'authors.*.id' => 'different:authors.*.id'
But it says 'The authors.0.id and authors.0.id must be different'
So what is a right way to validate this?
You want to use distinct rule.
When working with arrays, the field under validation must not have any duplicate values.
'foo.*.id' => 'distinct'
In GroceryCRUD i am getting the data from a table with these fields (as they appear in order in MYSQL)
id,
date_added,
views,
outhits,
clicks,
title,
description
and i want title + description to be at the top of the form when entering new rows or editing rows. how can this be done?
I solved this by using the columns() method and specifying the order in that list so in your case, try:
$this->grocery_crud->columns('title',
'description',
'id',
'date_added',
'views',
'outhits',
'clicks');