AJAX call to CodeIgniter controller with parameter - php

I know how AJAX call to CodeIgniter is working.
Edit for suggested answer
I tried redirection as a possible solution to my problem. I am not asking it as question. I am having problem passing parameter through URL and reusing view containing ajax post call. Also I am not aware how to post single value state_id which is already part of new_admission form.
I am loading city names for state_id of branch dynamically on $(document).ready()
When I call load_city() from admission() it works perfect.
XHR for load_city goes like:
localhost/project_folder/controller/load_city
But when I try edit_admission($studentId) it loads admission_view recursively inside <div id="city"></div>.
XHR for load_city goes like:
localhost/project_folder/controller/edit_admission/load_city
Here load_city is considered as parameter and edit_admission() is called recursively.
Controller:
public function load_city()
{
//load cities to $data from model
$this->load->view('city_view', $data);
}
public function admission()
{
//load init data for admission view from model
$this->load->view('admission_view', $data);
}
public function edit_admission($studentId)
{
//load init data for admission view from model
$this->load->view('admission_view', $data);
}
AJAX code:
function get_city() {
var parameters = {}; //instantiate the array
parameters['state_id'] = state_id;
$('#divcity').load('load_city', parameters, function (data) {
$('#city').combobox();
//code
});
};
load_city view:
<?php
echo '<select class="'.'form-control chzn-select col-lg-8 required'.'" id="'.'city'.'" name="'.'city'.'">';
echo '<option></option>';
foreach ($init_city['city_names'] as $row)
{
echo '<option value="'.$row->city_id.'">' .$row->city_name.'</option>';
}
echo '</select>';
?>
admission_view:
<div class="form-group">
<label class="control-label col-lg-4">City</label>
<div class="col-lg-8" id="divcity" name="divcity"></div>
</div>
I tried
public function edit_admission($studentId)
{
if(intval($studentId) > 0){
//load init data for admission view from model
$this->load->view('admission_view', $data);
} else if($studentId == 'load_city'){
//not passing post data to load_city()
redirect('branch/load_city');
}
}
Above code is not passing post data to load_city().
Also, I tried adding bellow code in routes.php
$route['edit_admission/load_city'] = 'load_city';
I did not get any success in both cases.

Related

Is it possible to render a view to a rendered page from the controller using Yii?

It there any way to create a "placeholder" inside the main view file for rendering other view files with specified data using Yii?
I want to individually process data in the controller then place them to a specified location in the view file before rendering.
Here is a widget example:
The widget class:
class MyWidget extends CWidget
{
public $someData;
public $mainData;
public function init()
{
}
public function run()
{
$this->render('mainView',array('data'=>$someData));
foreach($data as $dat)
{
if(dat["color"]=="red")
{
$display = 4;
}
else if(dat["color"]=="blue")
{
$display = 6;
}
etc....
//this is the fictional method for that purpose
$this->addToPage('mainView','subView','placeholderName',
array('display'=>$display,'mainData'=>$main));
}
}
}
The mainView file:
echo("<div class='someDesign'>");
echo($data);
$this->placeholder('placeholderName');
echo("</div>");
The subView file:
if($display>0 && $display<=4)
echo("<div class='dataColorG'>");
else if($display>0 && $display<=4)
echo("<div class='dataColorD'>");
echo $mainData;
echo("</div'>");
The solution based on Nikola's answer:
The widget class:
class MyWidget extends CWidget
{
public $someData;
public $mainData;
public function init()
{
}
public function run()
{
$output ="";
foreach($data as $dat)
{
if(dat["color"]=="red")
{
$display = 4;
}
else if(dat["color"]=="blue")
{
$display = 6;
}
//If it's a widget we need to use $this->controller->renderPartial() instead of $this->renderPartial()
$output.= $this->controller->renderPartial('subView',array('display'=>$display,'mainData'=>$main),true);
}
$this->render('mainView',array('subView'=>$output,'data'=>$someData));
}
}
The mainView file:
echo("<div class='someDesign'>");
echo($data);
echo($subView); //the 'placeholder'
echo("</div'>");
The subView file:
if($display>0 && $display<=4)
echo("<div class='dataColorG'>");
else if($display>0 && $display<=4)
echo("<div class='dataColorD'>");
echo $mainData;
echo("</div'>");
You can use renderPartial for this purpose. You can place the code for renderPartial isntead $this->placeholder('placeholderName'); e.g.:
$this->renderPartial('placeholderView', array($data));
Chech the other params - you can save to string or process js/css from the partials.
You said "previously rendered file" which I interpret that you have the main file already in view in the browser, and then you would like to have new data processed by the controller and passed back the view, for which you would need an ajax call from the main view file somehow (maybe through an ajax button). If so have a look at CHtml::ajaxButton.
This allows you to call a controller action and push the resulting view to a DOM placeholder (using the HTML id). The replace key in ajaxOptions of CHtml::ajaxButton would replace the contents of the DOM placeholder. e.g.
'replace' => '#placeholder_id'
Edit
replace will actually replace the whole DOM element. If you want to replace the html content inside the DOM element you can use update key in ajaxOptions
<div id="subviewPlaceholder_id">html content</div>
Here is an example, which resides inside a form. The button push will send form data as get params. Use your controller action to read the params and $this->renderPartial('subView',array(... params ...)) to send back your sub view:
<?php
echo '<div id="subviewPlaceholder_id"></div>';
echo CHtml::ajaxButton('Get Sub View Button Name',array(
'controller/getSubView','param1'=>$presetParam),
array( // this is the ajaxOptions
'type'=>'GET',
'update'=>'#subviewPlaceholder_id', // id of DOM element for subview
), array( // this is the htmlOptions
'class'=>'normalButton',
));
?>
Added
If you would like to place a sub view inside another view at initial render. Use #Nikola's suggestion
$this->renderPartial('subView',array(...params...));
Example main view file (followed by subview file). Place both files in your view folder:
<?php // mainView.php
echo '<h1>MAIN VIEW</h1>';
echo '<div class="class">'.$mainData->attribute1.'</div>';
echo '<div class="class">'.$mainData->attribute2.'</div>';
// render anything else
// parameters for subView (processing should be done in controller actually)
$display = $condition==$criteria?1:2;
//this is where subview.php would be placed
//You could get '_subView' from a variable and switch your subView according
//to your criteria.
$this->renderPartial('_subView', array(
'display'=>$display,
'param2'=>$param2));
echo '<div>MAIN VIEW CONTINUED</div>'; // add any other rendering for main view
?>
And here is your sub view (prefix "_" for partial views by convention)
<?php // _subView.php
if($display>0 && $display<=4)
echo("<div class='dataColorG'>");
else if($display>0 && $display<=4)
echo("<div class='dataColorD'>");
echo $param2; // add anything else to be rendered.
echo "</div>";
?>

last inserted id/latest inserted id function codeigniter

Codes:
View
<html>
<body>
<?php echo form_open('samplecontroller/sample'); ?>
<input type="text" name="samplename"/>
<input type="submit" value="go"/>
<?php echo form_close(); ?>
</body>
</html>
Controller
<?php
Class samplecontroller extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('Sample_insert');
}
function index()
{
$this->load->view('sample.php');
}
function show($data)
{
$this->load->view('sampleresult',$data);
}
function sample()
{
if($result = $this->Sample_insert->insert_into_sample())
{
$this->show($result);
}
}
}
?>
Model
<?php
Class Sample_insert extends CI_Model
{
function insert_into_sample()
{
$sample = array(
'samplename' => $this->input->post('samplename'),
);
$this->db->insert('sample', $sample);
$latest_id = $this->db->insert_id();
return $latest_id;
}
}
?>
The flow is that, i have 2 views. The other one contains only 1 text input, after which goes to controller then controller passes it on to model then model gets the value within the text input then inserts to my sample table.
The sample table has 2 columns, id(PK,AI) and name
after it inserts, on my model. i added a line, return $latest_id. Then passes goes back to my controller then passes it off to another view that only has
print_r($data);
After all that, it displays an error.
Message: Undefined variable: data
Im not sure where the flow went wrong or if i made a syntax mistake. If someone knows/expert on insert_id(), could you pin point where exactly i am wrong? anyways, ive made my research and been getting results on the web how buggy insert_id is. Im not sure if its true or not but ive been redirected mostly to forums wherein insert_id returns null and some say its a bug. Im hoping it isnt.
As per your comment, You have to do some changes in your controller.
function show($data)
{
$this->load->view('sampleresult',array("data"=>$data));
}
You can get inserted id in view in the name of $data.
For ex:
echo $data;
Edit: As per your comment in answer, For multiple row insert in model, add below code
$id_arr = array();
foreach($sample_data as $sample)
{
$this->db->insert('sample', $sample);
$id_arr[] = $this->db->insert_id();
}
return $id_arr;
Now in your view, you will get ids in $data
foreach($data as $id)
{
echo $id;
}

getting values of second select from db based of first select box selection in codeigniter

I Need help on how can i get values of second select box based on first select box
This is view:
$(document).ready(function() {
$('#state').change(function() {
// Get an instance of the select, and it's value.
var state = $(this),
stateID = state.val();
// Add if statement to check if the new state id
// is different to the last to prevent loading the same
// data again.
// Do the Ajax request.
$.ajax({
url : 'http://localhost/ci_ajax/select/get_cities/'+stateID, // Where to.
dataType : 'json', // Return type.
success : function(data) { // Success :)
// Ensure we have data first.
if(data && data.Cities) {
// Remove all existing options first.
state.find('option').remove();
// Loop through each city in the returned array.
for(var i = 0; i <= data.Cities.length; i++) {
// Add the city option.
state.append($('option').attr({
value : data.Cities[i].value
}).text(data.Cities[i].city));
}
}
},
error : function() {
// Do something when an error happens?
}
});
});
});
<form action="" method="post">
<select name="state" id="state">
<option>Select</option>
<?php foreach($states as $row):?>
<option value="<?php echo $row->id?>"><?php echo $row->states;?></option>
<?php endforeach;?>
</select>
<select id="cities" name="cities">
<option>Select</option>
</select>
This is controller:
class Select extends CI_Controller{
function index(){
$data['states']=$this->load_state();
$this->load->view('form',$data);
}
function load_state(){
$this->load->model('data_model');
$data['states']=$this->data_model->getall_states();
return $data['states'];
}
function get_cities() {
// Load your model.
$this->load->model('data_model');
// Get the data.
$cities = $this->data_model->get_cities();
// Specify that we're returning JSON.
header('content-type: application/json');
// Return a JSON string with the cities in.
return json_encode(array('Cities' => $cities));
}
}
This is model:
class Data_model extends CI_Model{
function getall_states(){
$query=$this->db->get('states');
if($query->num_rows()>0){
foreach($query->result() as $row){
$data[]=$row;
}
return $data;
}
}
function get_cities(){
$this->db->select('id,cities');
$this->db->from('cities');
$this->db->where('s_id',$this->uri->segment(3));
$query=$this->db->get();
if($query->num_rows()>0){
foreach($query->result() as $row){
$data[]=$row;
}
return $data;
}
}
}
Please help on this hopefully provide the correct code.
Because you are accessing the get_cities() function directly, rather than from another function in the controller, your return statement will not actually print the json array to the page.
return json_encode(array('Cities' => $cities));
There are 3 ways to print it: the first is to print or echo the json array (bad practice), the second is to use a view that prints the raw text sent to it. I.E.
$this->load->view('raw', array('data' => json_encode(array('Cities' => $cities)));
With raw.php being just:
<?php print $data; ?>
Or finally you can use the set_output() function in the output class like this:
$this->output->set_output(array('data' => json_encode(array('Cities' => $cities)));
You may also want to make your function load_state() private if it is only going to be accessed from the index() function.
You may have other problems with your code but that is the most obvious one.

multiple zend pagination controls via ajax and jquery

Can someone help me achieve multiple zend pagination in a view using ajax. I have managed to achieve single pagination no problem, but now i want to perform more than 1.
this is my setup:-
added to the bootstrap:-
public function _initPaginator(){
Zend_Paginator::setDefaultScrollingStyle('Sliding');
Zend_View_Helper_PaginationControl::setDefaultViewPartial('pagination_control.phtml');
}
'pagination_control.phtml' has been taken from the zend framework manual.
added to the controller:-
public function init()
{
parent::init();
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('view', 'html')
->initContext();
}
added this to the controller action:-
public function viewAction()
{
$query = $this->_em->createQueryBuilder()
->select('t')
->from('Ajfit\Entity\Ticket', 't')
->where('t.engineerFk = :engineer')
->orderBy('t.dt', 'desc')
->setParameter('engineer', $engineer)
->getQuery();
$paginator = new Paginator($query);
$adapter->getIterator();
$zend_paginator = new \Zend_Paginator($adapter);
$zend_paginator->setItemCountPerPage(3)
->setCurrentPageNumber($this->_getParam('page'));
$this->view->ticketPaginator = $zend_paginator;
}
added this to the view:-
<div>
<div id="ticket-history">
<?php
echo $this->render('profile/view.ajax.phtml');
?>
</div>
</div>
<script>
$(document).ready(function() {
$('.pagination-control').find('a').live('click', function(e) {
var link = $(this);
$('#ticket-history').load(link.attr('href'), { format: 'html' });
return false;
});
});
</script>
my 'profile/view.ajax.phtml' script contains:-
<?php
echo '<table border="0" width="100%" cellspacing="3" cellpadding="3"><tr>';
foreach($this->ticketPaginator as $ticket){
echo '<td>' . $ticket->getSubject() . '</td>';
}
echo '</tr></table>';
?>
<?php
echo $this->paginationControl($this->ticketPaginator);
?>
This all works fine, however, how would one go about adding a second or third paginator to this view for a different doctrine entity?
Any help would be much apprieciated.
Thanks
Andrew
for that you have to use multiple addActionContext in init()
$this->_helper->ajaxContext->addActionContext('view', 'html')->initContext();
$this->_helper->ajaxContext->addActionContext('list', 'html')->initContext();
and you can continue
add action in controller as listAction() for paginator create file as list.ajax.phtml also and add required code inside them
This problem can be resolved if you manipulate the pagination links to let it call the other action.
For example: In the View Part, you can use the fourth parameter of the paginationControl method to define the links which refers to another action. This link should then be called in pagination_control.phtml.

How to pass a variable from view to controller in codeigniter

I want to pass a language id for each link i click from my view to controller.
My view code is
<?php foreach ($languages as $lang) { ?>
<li>
</li>
<?php } ?>
My controller is
public function box($box_id=null, $language_name=null, $language_id=null) {
/// my function code
echo $box_id;
echo $language_name;
echo $language_id;
$data['languages'] = $this->Home_model->getLanguages($box_id);
}
The languages array contain the language id and language name
i want the name to be in url but not the id
The url looks like this
http://localhost/mediabox/home/box/12/en
if i send the language id in url it is then visible otherwise it is not visible in the controller.
How can I get language id for each link in controller without sending it in url
Thanks
pass the language name in the url without the ID, compare to languag_name column in table.
Lets assume you have url: http://localhost/mediabox/home/box/en
controller
<?php
# I wont write a controller but you should know how to do that, im also writing code as if you are just focusing on getting language.
public function box( /**pass in your other uri params as needed **/ $lang_name = 'en'){
#you could load this in the constructor so you dont have to load it each time, or in autoload.php if your using it site wide.
$this->load->model('lang_model', 'langModel');
#this example shows loading the library and running the function
$this->load->library('lang_library');
$this->lang_library->_getLang($lang);
#this example shows putting the getLang function inside the controller itsself.
self::_getLang($lang);
}
library/private function
<?php
private functon _getLang($lang = 'en'){
#run the query to retrieve the lang based on the lang_name, returns object of lang incl id
$lang = $this->langModel->getLang($lang_name);
if (!$lang){
die('language not found');
}else{
return $lang;
}
lang model
<?php
public function getLang($lang_name = 'en'){
$this->db->where('lang_name', $lang_name);
$this->db->limit(1);
$q = $this->db->get('languages');
if ($q->mysql_num_rows > 0){
return $q->result();
}else{
return false;
}
}
you will then have a variable with object associated to it then you can simply call $lang->lang_name; or $lang->lang_id;
Session storage
<?php
#you could call this in the beginning after using an ajax `$.post();` to retrieve the ID.. the easiest route though is whats above. I use this in my REST APIs
$this->session->set_userdata('lang', $lang);
Your confusion is in 'passing back' to the controller. Don't think of it as from controller => View (passing it say $data['something'] variables).
Its basically a <form>, so take a look at form helper and then at form validation.
That will give you an idea of how to create a form using codeigniter syntax.
In your controller, you would do a validation, and if it matches the language (or whatever you submit), then you can utilize sessions to save it for every page (so you don't need it in the URL).
Sessions are very simple and saving an item is as easy as:
$this->session->set_userdata('varname', 'value');
Later, on every other controller, you can check the variable
$language = $this->session->userdata('varname');
// load language etc;
Make a table with language ID and Language name in the database, just pass the language name to the controller and get the language ID by doing a db call.
You could do it using jQuery. Something like;
In View;
<ul id="language_selector">
<?php foreach ($languages as $lang) { ?>
<li>
<a href="javascript:;" class="change-language" data-language="<?php echo $lang['language_name']?>" data-box="<?php echo $template_data['box_id']?>">
<img src="<?php echo base_url(); ?>public/default/version01/images/country_<?php echo $lang['language_name'] ?>.png" width="27" height="18" border="0" />
</a>
</li>
<?php } ?>
</ul>
The JS;
$(function() {
$('.change-language').live('click', function() {
var language_name = $(this).data('language');
var box_id = $(this).data('box');
$.ajax({
url: '/home/box/'+language_name,
type: 'post',
data: 'box_id='+box_id,
success: function( data ) {
self.parent.location.reload();
},
error: function( data ) {
alert('oops, try again');
}
});
});
});
The controller:
public function box($language) {
$box_id = $this->input->post('box_id');
// do a llokup on the language as suggested by #vivek
}
You are telling CodeIgniter that you will be receiving both the language name and id in your action.
public function box($box_id=null, $language_name=null, $language_id=null) {
}
Change that to just
public function box($box_id=null, $language_name=null) {
}
For your example URL you should then get $box_id == 12 and $language_name == 'en'.
Then lookup the language id by using it's name either in a helper or as part of a Language model as Mike suggests.

Categories