How to access property of looped item in view parser? - codeigniter

The documentation on the view parser deals with conditions, but their example deals only with an explicitly defined variables that has no relation with a looped item. Which works for situations like this:
{ if $var === 'foo' }
<p>This is foo</p>
{ endif }
So if I wanted to check the value of a property on a looped item, how would I do that? Ideally, I expect something like this (in this example, users is an array):
<ul>
{ users }
<li>{ name }
{ if id == 1 }
This is the first user
{ endif }
</li>
{ /users }
</ul>
But, with or without the dollar-sign in front of the id in that condition, it complains that the value isn't defined. Perhaps something like $user['id'] would work, but how can I know the name of the variable that CodeIgniter uses for its inner iterations?
Edit 1: Data array
$data = [
'users' => [
[
'id' => 1,
'name' => 'John'
], [
'id' => 2,
'name' => 'Ben'
]
]
];

Looping is explained in the Docs at View Fragments.
You need to combine it with conditional Logic as below:
<ul>
{ users }
<li>{ name }
{ if $id == 1 }
This is the first user
{ endif }
</li>
{ /users }
</ul>

Related

Laravel replace abbreviations by words in blade

We have specific columns in tables having a status, these are abbreviations, we want these short words beeing replaced by full words.
for example:
E => Error
R => Running
D => Done
I already seen things as Laravel Translation, but this is not what we need I suppose? This is not a language translation.
Looking for something where I can set the full words of each abbreviation, and show these full words in blade like:
#get_full_word(column_name)
which will output the full name
I think it is a best case for Mutators.
class Test extends Model
{
protected $fullStatus = [
'E' => 'Error',
'R' => 'Running',
'D' => 'Done',
];
public function getFullStatusAttribute()
{
return $this->fullStatus[
$this->status
];
}
}
And of course if its in many Classes, it would be nice to create a Trait that holds the code.
You can create your own blade directive.
Blade::directive('abbreviation', function ($abbreviation) {
return "<?php echo Abbreviation::get($abbreviation); ?>";
});
where Abbreviation is your class with abbreviations, like this
class Abbreviation
{
private $abbreviations = [
'E' => 'Error'
'R' => 'Running'
'D' => 'Done'
];
public static function get($abbreviation)
{
return $abbreviations[$abbreviation];
}
}
Than you can use it in your blade #abbreviation('D')

Laravel Model Parsing Array

I have an object in my database that I am trying to retrieve in the Model and parse through to display the text in the blade template. I am not quite sure how to get this to parse correctly. Thank you.
public function getStep1()
{
$step1 = $this->details()->get();
foreach($step1 as $step1)
{
$step1 = $step1->step_1;
return $step1;
}
}
This gets me the following output that I don't know how to parse through. I have tried $step1[0], but that just gives me a [ nothing else.
[["$50,000-$100,000","More than $100,000"]]
My Blade template is simply this...
{{ $question->getStep1() }}
Thank you for your help.
Update:
When I do a var_dump, it says that my "steps" are stored as strings. Is that what's causing a problem? I still can't get within the [].
array (size=9)
'id' => int 1
'question_id' => int 55
'step_1' => string '[["$50,000-$100,000","More than $100,000"]]' (length=43)
'step_2' => string '[["Step2-option1","Step2-option2","Step2-option3"]]' (length=51)
'step_3' => string '[["Step3-option2"]]' (length=19)
'step_4' => null
'step_5' => null
'created_at' => string '2018-10-03 12:29:05' (length=19)
'updated_at' => string '2018-10-03 12:29:05' (length=19)
Instead of returning double array you can just append results to a temporary array and then return that array, check the example code:
public function getStep1()
{
$tempArr = [];
$steps = $this->details()->get();
foreach($steps as $step1)
{
$tempArr[] = $step1->step_1;
}
return $tempArr;
}
Your template code should now iterate over an array we have built right now, so a foreach is required. Like below:
#foreach($question->getStep1() as $step)
// do something with $step
#endforeach
public function getStep1()
{
$steps = $this->details()->get();
$totalSteps = collect();
foreach($steps as $step1)
{
foreach ($step1 as $step)
{
$toalSteps->push($step);
}
}
return $totalSteps;
}

Passed data lost in Laravel paginator starting from page 2

I am trying to list people by their appRole. Here's the controller:
public function indexByAppRole(Request $request, $appRoleId)
{
$h1 = AppRole::where('id', $appRoleId)->first()->name;
return view('admin.people.index', [
'people' => $this->people->byAppRole($appRoleId),
'appRoles' => $this->appRoles->forAll(),
'h1' => 'Role: '. $h1,
]);
}
Paginator is used in the repository:
public function byAppRole($appRoleId)
{
return Person::where('person_app_role.app_role_id', $appRoleId)
->join('person_app_role', 'person_app_role.person_id', '=', 'people.id')
->select('people.*') // fix ID confusion but why?
->paginate(20);
}
The main view lists the returned people. In the sidebar, I have the following list as side-navigation:
<ul class="list-group nav nav-pills nav-stacked">
#foreach ($appRoles as $appRole)
<li>
{{ str_plural($appRole->name) }}
</li>
#endforeach
</ul>
The navigation list works on page 1 of search results or listings, but the list is not showing up on page 2 and subsequent pages. What did I do wrong?
I solved the problem. For AppRole, I also used a paginator, so this was fixed by using all() instead of paginate() to get all appRoles.
// Before...........
public function forAll()
{
return AppRole::paginate(20);
}
And:
// After............
public function forAll()
{
return AppRole::all();
}

Conditional Validation in Yii2

I have a radio button with two values (required field) based on that value one field is shown (there are two fields which are intially hidden, its shown based on value of radio button) which should be required. So I used conditional validation for the initially hidden fields.
This is my model code:
public function rules()
{
return [
[['receipt_no', 'date_of_payment', 'payment_method_id',
'total_amount'], 'required'],
['nonmember_name', 'required', 'whenClient' => function($model)
{
return $model->is_member == 2;
}, 'enableClientValidation' => false],
['member_id', 'required', 'whenClient' => function($model)
{
return $model->is_member == 1;
}, 'enableClientValidation' => false],
[['receipt_no', 'date_of_payment', 'payment_method_id',
'total_amount','is_member'], 'required','on' => 'receipt'],
];
}
I use a scenario receipt, is_member is the radio button field. If I select a value of 1 for is_member then field member_id is visible and it should be a required one. If is_member has a value 2 then nonmember_name is displayed and it should become a required field. With my code in model I managed to achieve it. But now other actions (saving a new row of data into model) using this model is having error
Array ( [nonmember_name] => Array ( [0] => Name cannot be blank. ) )
So my question is how can I make conditional validation specific to a scenario (I think that my error is due to required rule defined in conditional validation )
EDIT:
This is my radio button
<?= $form->field($model, 'is_member')->radioList(array('1'=>'Member',2=>'Non Member'))->label('Member or Not'); ?>
In rules
public function rules()
{
return [
[
'nonmember_name',
'required',
'when' => function ($model) {
return $model->is_member == 2;
},
'whenClient' => "function (attribute, value) {
return $('#id').val() == '2';
}"
]
];
}
I prefer to use functions inside the model's rules, which makes it a lot easier to work with in the future.
One thing to mention that a lot of answers don't mention, is that you MUST manually re-trigger the Yii2 client side validation!
$("#w0").yiiActiveForm("validateAttribute", "createuserform-trainer_id");
In my example below, there are 2 types of accounts: trainer and trainee. In my admin panel, the admin can create a new user. If they choose "trainer" there is nothing more to do. If they choose a "trainee", that "trainee" must be assigned a "trainer" to go under.
So in code terms:
If user role == trainee, trainer_id is required and show it's form input.
Else hide the trainer_id input and trainer_id will not be required.
Model rules:
public function rules()
{
return [
[
'trainer_id', 'required', 'when' => function ($model) {
return $model->role == 2;
}, 'whenClient' => "isUserTypeTraineeChosen"
],
];
}
View after your form:
<?php $this->registerJs('
function isUserTypeTraineeChosen (attribute, value) {
if ($("#createuserform-role").val() == 2) {
$(".field-createuserform-trainer_id").show();
} else {
$("#createuserform-trainer_id").val(null);
$(".field-createuserform-trainer_id").hide();
}
return ($("#createuserform-role").val() == 2) ? true : false;
};
jQuery( "#createuserform-role" ).change(function() {
$("#w0").yiiActiveForm("validateAttribute", "createuserform-trainer_id");
});
jQuery( "#createuserform-role" ).keyup(function() {
$("#w0").yiiActiveForm("validateAttribute", "createuserform-trainer_id");
});
'); ?>
Note: This is a dropdown list, so change and keyup both are necessary to accurately detect it's change statuses. If your not using a dropdown, then both may not be necessary.
I also have targeted the trainer_id input to be hidden by default using CSS, as the default user type is a trainer.

How do I pass a selectbox variable to the View from the Controller in CodeIgniter?

I want to pass a variable (selectbox id, which comes from database) to the view from the controller, but do not know how to do it.
Your original question wasn't that clear, but after reading the comments you could do this.
Controller
//whatever function you're using to populate your original array below.
$data['all'] = $this->model_name->getData();
//then run that data through a foreach loop to populate the dropdown variable.
foreach($data['all'])
{
$data['idDropDown'][$data['all']['id']]=$data['all']['ad'];
}
This will pass an array like: [455]=>Aliağa, [456]=>Balçova to the view as $idDropDown along with your original data as $all
Then in the view just used CI's form dropdown.
echo form_dropdown('id',$idDropDown);
Let's say you have a controller called article and a method index then in your view you will have :
<?php
echo form_open('article/index');
echo form_input('text');
echo form_close;
?>
And in your controller something like:
public function index()
{
if($this->input->post()) {
$this_is_catched_text = $_POST['text'];
}
}
This is without validation and other stuff. Just you get the idea how it works.
In your case it will be like this
$ilce = array(array("id" => 455, "il_id" => 35,"ad" => "Aliağa"),
array("id" => 456, "il_id" => 35, "ad" => "Balçova"));
$options = array();
foreach($ilce as $x) {
$options[$x['id']] = $x['ad'];
}
echo form_dropdown('names', $options);

Resources