Let say we are loading two or more views in the same class method like so:
$this->load->view('header');
$this->load->view('body');
$this->load->view('footer');
and you decide to create a variable inside the head view ($cat_name) like this example:
<?php
foreach ($categories as $key => $value) {
$selected = FALSE;
if ($this->router->class == 'category' && $this->router->method == 'id' && $this->uri->segment(3) == $value->id) {
$cat_name = $value->name;
$selected = TRUE;
}
?>
<option value="<?= $value->id; ?>" <?= ($selected ? 'selected' : ''); ?>><?= $value->name; ?></option>
<?php } ?>
This needed a loop to get that variable.
I want to pass that variable ($cat_name) to the next view without redoing the loop, that is just a waste.
what I am trying to achieve is minimizing the number of loops.
instead of loading all of that in controller load it in your view
create new file, let say template
$this->load->view('template',$variable);
and in your template
//do the loop here
$this->load->view('header');
$this->load->view('body');
$this->load->view('footer')
You need to create model for generating selects if You want to save MVC in Your project. I know, that's looks strange, but it will help You many times after
Controller
// load model
$this->load->model('myselect_model');
// get array with marked element
$select_data = $this->myselect_model->setSelected($categories, $this->router->class, $this->router->method, $this->uri->segment(3));
// get filled html
$my_html_select = $this->load->view('select_tpl',array('select'=>$select_data),TRUE);
// use it at any controller
$this->load->vars(array('my_select'=>$my_html_select));
// some views
$this->load->view('header');
$this->load->view('body');
$this->load->view('footer');
Model 'myselect_model'
function setSelected($items, $uri_controller,$uri_method, $uri_value){
// createing temp array for our list
$tmp = array();
foreach($items as $key=>$value){
// appending item
$tmp['options'][$key] = $value;
if ($uri_controller == 'category' && $uri_method == 'id' && $uri_value == $value->id)
{
// saving selected for any reason to use after
$tmp['selected'] = array('name'=>$value->name, 'id'=>$value->id);
// marking this item as selected
$tmp['options'][$key]['selected'] = TRUE;
}
}
// returning completed array
return $tmp;
}
View 'select_tpl'
<?php if(!empty($select)){?>
<select>
<?php foreach($select['options'] as $option){?>
<option value="<?=$option->id?>"<?=(isset($option['selected']) && $option['selected']==TRUE ? " selected=\"selected\"" : "")?>><?=$option->name?></option>
<?php }
</select>
<?php } ?>
views/header
<body><?=$my_select?><i>template here</i>
views/body
<p>some html here and our select goes here-> <?=$my_select?></p>
You could try like this:
Create a model like so:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Class Custom_model extends CI_Model
{
public function __construct()
{
parent::__construct();
}
function printSelect(){
// Do some logic and looping here
$html = "<select><option>...</option></select>";
return $html
}
}
Then call that model from your views like so..
$this->custom_model->printSelect();
Remember to load the model first.
$this->load->model('path/to/your/model/folder/custom_model');
This way, every time you want to print your you can simply call that method from your view.
I hope this helps.
Related
what is the best code for sidebar partial for multilevel?
Is it just do in Controller like :
public function tambahNota()
{
$head['title'] = 'Tambah Nota';
if($this->session->userdata('userLevel') == 1){
$this->load->view('partials/sidebarAdmin');
} elseif($this->session->userdata('userLevel') == 2){
$this->load->view('partials/sidebarUser');
}
$this->load->view('partials/footer');
$this->load->view('nota/tambahNota');
.. or in View partials/sidebar?
<?php if ($this->session->userdata('userLevel') == 1) {?>
..script of admin sidebar..
<?php } else if($this->session->userdata('userLevel') == 2) {?>
..script of user sidebar..
<?php } ?>
Thank you.
Hi #Goldplate it is good to keep it at the view. Although both ways works, keeping it in the view makes it easy to change filenames when you need to.
You can create a helper function to keep things simple, for example:
Create a helper with the name template_helper.php in the helpers directory.
Add the code below.
<?php
defined('BASEPATH') or exit('No direct script access allowed');
function load_partial($view_path, $view_data = null)
{
$ci =& get_instance(); //get_instance is an instance of codeigniter object
if (strstr($view_path, '.')) {
$view_path = str_replace('.', '/', $view_path);
}
$ci->load->view($view_path, $view_data);
}
And you can use it like this:
<?php if ($this->session->userdata('userLevel') == 1) {?>
load_partial('sidebars.level_one');
<?php } else if($this->session->userdata('userLevel') == 2) {?>
load_partial('sidebars.level_two');
<?php } ?>
So here "sidebars" is a directory that contains files level_one.php and level_two.php
If you see a dot in 'sidebars.level_one' it is just replacing a forward slash '/' and for easy access.
This is just to give you an idea. Let me know if it helps.
Both the process is good. It up to you to choose yours.
As it is templating, I like to keep it the view. so, later on, I can easily find the file for edit.
I'm working on a similar thing as this one. But I'm trying to assign button either "Join" or "Enter" based on if someone joined the group. The problem is that I'm not sure how I can pass the variable from the category ID ($cats_id) to the view file.
I created a function in the model that checks if the row exists and returns true.
// check if joined the group
public static function checkIfJoined($cats_id)
{
$database = DatabaseFactory::getFactory()->getConnection();
$users_id = Session::get('user_id');
$sql = "SELECT cats_id,users_id FROM categories_joined WHERE users_id = :users_id AND cats_id = :cats_id";
$query = $database->prepare($sql);
$query->execute(array(':users_id' => $users_id, ':cats_id' => $cats_id));
// fetchAll() is the PDO method that gets all result rows
if ($query->rowCount() >= 1 || Session::get('user_account_type') == 7) {
return true;
}
}
Then in Controller I render the model to the view.
public function index()
{
$cats_id = ""; // this doesn't work right obviously
$this->View->render('dashboard/index', array(
'categories' => DashboardModel::getAllCategories(),
'joined' => DashboardModel:: checkIfJoined($cats_id)
));
}
in the view I pass the variable from the preview function 'categories'.
<?php if ($this->categories) { ?>
<?php foreach($this->categories as $key => $value) { ?>
...
<?php $cats_id = $value->cat_id; if ( $this->joined == true ): ?>Enter
<?php else: ?>Join
<?php endif; ?>
You can never pass anything from view to controller because view is parsed after controller.
What you can do here is use model directly by calling DashboardModel::checkIfJoined($cats_id) in your view but that's not perfect approach.
It'll be better to prepare that data in the controller and then pass it to view.
Example controller
public function index()
{
$this->View->render('dashboard/index', array(
'categories' => DashboardModel::getAllCategories(),
'userCategories' => DashboardModel::getUserCategories()
));
}
Example view
<?php
if ($this->categories) {
foreach ($this->categories as $key => $value) {
if (in_array($value->id, $this->userCategories) {
echo 'Joined';
} else {
echo 'Join';
}
}
?>
In this example DashboardModel::getUserCategories() should return results from SELECT cats_id FROM categories_joined WHERE users_id = :users_id.
I'm trying to add an option from the controller to the view directly .. the moment I get the array data from there with the following code:
public function select_dependent() {
$aData = array(); //Variable para pasar a la vista
$data = $this->input->post('id');
$tipus = $this->input->post('tipus');
if($tipus == "modelo") {
$aData['aModels'] = $this->pedidos_model->get_modelos($data);
}
}
In the view, i have the following code:
<select name="modelo" class="span8" id="modelo">
<?if(isset($aModels)):?>
<?foreach($aModels as $row):?>
<option value="<?=$row['IDPRODUCTOS']?>"><?=$row['NOMBRE']?></option>
<?endforeach;?>
<?endif;?>
</select>
And in the model I have this:
public function get_modelos($valor) {
$oQuery = $this->db->query("dbo.CO_GETPRODUCTO #IDTIPOS ='".$valor."'");
$aResult = $oQuery->result_array();
return $aResult;
}
Can you help me? Thank you!
You may use the Form Helper to generate the select/dropdown element easily:
// In your controller method
$this->load->helper('form');
// ...
if($tipus == "modelo") {
$aData['aModels'] = $this->pedidos_model->get_modelos($data);
$aData['selected'] = 'use_a_value_to_be_selected';
// Load the view and pass the $aData
$this->load->view('blogview', $aData);
}
// In your view
echo form_dropdown('modelo', $aModels, $selected, 'class="span8" id="modelo"');
Your question is not so clear about the problem so can't be more specific but you got the idea.
I'm stacked on this matter. I have a model that retrieves data from a mysql database
class load_model extends CI_Model{
function __construct(){
parent::__construct();
}
Function loadsuppliers()
{
$this->db->select('SupplierID, Name');
$records=$this->db->get('supplier');
$data=array();
foreach ($records->result() as $row)
{
$data[$row->SupplierID] = $row->Name;
}
return ($data);
}
}
?>
This model submits value to a function in my controller
public function getSupplier()
{
$this->load->model('load_model');
$data['unit'] = $this->load_model->loadsuppliers();
$this->load->view('SupplierMGT', $data);
}
and I want to display the retrieved data to my view as a combo box. I tried to check if I am able to retrieve database values using echo json_encode($data) and it returns {"unit":{"2":"test","3":"Delta"}} ,
Could you help me with this? I tried using
<?php foreach($unit as $result):
print_r($result);
endforeach;?>
to check if i am able to pass the value but i failed.
Small changes in the model:
function loadsuppliers()
{
$this->db->select('SupplierID, Name');
$records=$this->db->get('supplier');
$data=array();
if($records->num_rows() > 0){
$data = $records->result_array();
}
return ($data);
}
In your view SupplierMGT.php write this:
<select name="" id="" multiple="">
<?php
if(isset($unit) && is_array($unit) && count($unit) > 0){
foreach($unit as $key=>$each){
?>
<option value="<?=$each['SupplierID']?>"><?=$each['Name']?></option>
<?php
}
}
?>
</select>
Where should we process mysql queries in CodeIgniter application?
For example in a simple project we do like this :
for controller:
class Blog extends CI_Controller {
function posts(){
$data['query'] = $this->blog_model->index_posts();
$this->load->view('blog_view', $data);
}
}
and in view :
<?php
while ($post = mysql_fetch_object($query)):
?>
<div>
<p><?= $post->body; ?></p>
</div>
<?php endwhile; ?>
But, if we want to do something with body of post before print where should it be done?
For example, I want to write a function that formats the body of post and pass the body to it before doing echo.
Where should it be placed according to CoeIgniter's structure and recommended practices? (best option)
in the controller? (if so , how to use it)
in the view?
write a helper?
other approaches ?
Here's what is recommended:
Controller:
function posts() {
$this->load->model("blog_model");
$data['rows'] = $this->blog_model->index_posts();
$this->load->view("blog_view", $data);
}
Model: (blog_model.php)
function index_posts() {
$this->load->database();
$query = $this->db->get('your_table');
$return = array();
foreach ($query->result_array() as $line) {
$line['body'] = ... do something with the body....
$return[] = $line;
}
return $return;
}
View: (blog_view.php)
<?php foreach ($rows as $line): ?>
<div>
<p><?php echo $line['column']; ?></p>
</div>
<?php endforeach; ?>
Basically what happens is your model returns a multidimensional array that is passed the view and processed using a foreach() loop.
Good luck!
If you want to reuse that function create a helper. If you want this function only once put it in your controller and call from that controller.
Models are just for accessing database or maybe in few other cases, but mostly just for accessing things in database or editing, deleting etc. and sending the result to controller for further processing.
In your case I would stick with helper.
E.g. you will create a file top_mega_best_functions.php and put it inside helpers folder.
Than you write ther e.g. something like
function red_text($input) {
echo '<span style="color: red;">';
echo $input;
echo '</span>';
}
Then load the helper in your autoloader file or load before using.
And use in your view or controller like
$blablabla = "This text will be red";
red_text($blablabla);