I have a question about cakePHP. I create two drop down lists in my view. When the user changes the value in one list, I want the second to change. Currently, I have this working like this: An on click event fires when the user selects from list box one. This fires a jQuery ajax function that calls a function from my controller. This is all working fine, but how do I re-render my control, asynchronously (or, view)? I i know I could just serialize the array to json and then recreate the control in javascript, but there seems like there should be a more "CakePHP" way. Isn't that what render is for? Any help would be great. Here's the code I have so far:
jQuery:
function changeRole(getId){
$.ajax({
type: 'POST',
url: 'ResponsibilitiesRoles/getCurrentResp',
data: { roleId: getId },
cache: false,
dataType: 'HTML',
beforeSend: function(){
},
success: function (html){
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
}
});
View:
<?php
echo 'Roles:';
echo'<select name="myOptions" multiple="multiple">';
foreach ($rolesResponsibility as $role) {
echo' <option onclick="changeRole(this.value);" value="'; echo $role["ResponsibilitiesRole"]["role_id"]; echo '">'; echo $role["r"]["role_name"]; echo '</option>';
}
echo '</select>';
echo 'Responsbility:';
echo'<select name="myOptionsResp" multiple="multiple">';
foreach ($respResponsibility as $responsibility) {
echo' <option value="'; echo $responsibility["responsibility"]["id"]; echo '">'; echo $responsibility["responsibility"]["responsibility_name"]; echo '</option>';
}
echo '</select>';
?>
Controller function:
public function getCurrentResp(){
$getId = $this->request->data['roleId'];
$responsibilityResp = $this->ResponsibilitiesRole->find('all',
array("fields" => array('role.role_name','ResponsibilitiesRole.role_id','responsibility.*'),'joins' => array(
array(
'table' => 'responsibilities',
'alias' => 'responsibility',
'type' => 'left',
'foreignKey' => false,
'conditions'=> array('ResponsibilitiesRole.responsibility_id = responsibility.id')
),
array(
'table' => 'roles',
'alias' => 'role',
'type' => 'left',
'foreignKey' => false,
'conditions'=> array('ResponsibilitiesRole.role_id = role.id')
)
),
'conditions' => array ('ResponsibilitiesRole.role_id' => $getId),
));
$this->set('respResponsibility', $responsibilityResp);
//do something here to cause the control to be rendered, without have to refresh the whole page
}
The js event is change fired on the select tag and NOT click
You can use the Form Helper to build your form.
Pay attention Naming things following the cakephp way.
Because your code is a bit confused i will make other simple example:
Country hasMany City
User belongsTo Country
User belongsTo City
ModelName/TableName (fields)
Country/countries (id, name, ....)
City/cities (id, country_id, name, ....)
User/users (id, country_id, city_id, name, ....)
View/Users/add.ctp
<?php
echo $this->Form->create('User');
echo $this->Form->input('country_id');
echo $this->Form->input('city_id');
echo $this->Form->input('name');
echo $this->Form->end('Submit');
$this->Js->get('#UserCountryId')->event('change',
$this->Js->request(
array('controller' => 'countries', 'action' => 'get_cities'),
array(
'update' => '#UserCityId',
'async' => true,
'type' => 'json',
'dataExpression' => true,
'evalScripts' => true,
'data' => $this->Js->serializeForm(array('isForm' => false, 'inline' => true)),
)
)
);
echo $this->Js->writeBuffer();
?>
UsersController.php / add:
public function add(){
...
...
// populate selects with options
$this->set('countries', $this->User->Country->find('list'));
$this->set('cities', $this->User->City->find('list'));
}
CountriesController.php / get_cities:
public function get_cities(){
Configure::write('debug', 0);
$cities = array();
if(isset($this->request->query['data']['User']['country_id'])){
$cities = $this->Country->City->find('list', array(
'conditions' => array('City.country_id' => $this->request->query['data']['User']['country_id'])
));
}
$this->set('cities', $cities);
}
View/Cities/get_cities.ctp :
<?php
if(!empty($cities)){
foreach ($cities as $id => $name) {
?>
<option value="<?php echo $id; ?>"><?php echo $name; ?></option>
<?php
}
}
?>
Related
I have created a registration form that has a dropdown field, but I am unable to get it to link into the database to register the selection. I have form validation turned on, but it keeps saying that no value has been selected.
My other inputs work, as they're user entered. However, the values in this dropdown do not register as any value. Any assistance would be appreciated.
Thanks!
View
<div class = "form-group">
<?php echo form_label('Mobile Carrier'); ?><br/><!--Form Label-->
<?php
$data = array(
'None' => 'None',
'att' => 'AT&T',
'verizon' => 'Verizon',
'sprint' => 'Sprint',
'tmobile' => 'T-Mobile'
);
?>
<?php echo form_dropdown('Mobile Carrier', $data, 'None'); ?>
Controller
public function register(){
$this->form_validation->set_rules('mobile_carrier', 'Mobile Carrier', 'required'); }
User Model
public function create_user(){
$data = array(
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'email' => $this->input->post('email'),
'phone_number' => $this->input->post('phone_number'),
'mobile_carrier' => $this->input->post('mobile_carrier'),
'username' => $this->input->post('username'),
'password' => $encrypted_pass
);
$insert_data = $this->db->insert('users', $data);
return $insert_data;
}
you are assigning the wrong name attribute when creating the dropdown list:
<?php echo form_dropdown('Mobile Carrier', $data, 'None'); ?>
the name attribute must match your $this->input->post('mobile_carrier') in your model. so the correct use would be:
<?php echo form_dropdown('mobile_carrier', $data, 'None'); ?>
more information: https://www.codeigniter.com/userguide3/helpers/form_helper.html, scroll to form_dropdown([$name = ''[, $options = array()[, $selected = array()[, $extra = '']]]])
I'm using the cakephp uploader plugin by Miles Johnson. I like the plugin and I've got it working to be able to upload photos for a photo model.
The problem I'm running into is that when I try to edit an existing record, instead of replacing the photo associated with the record I'm editing a new record is created. The new record has all the same information with the exception of the new photo that's been uploaded.
Here's how the photo model looks:
'Uploader.Attachment' => array(
'imgPath' => array(
// 'name' => '', // Name of the function to use to format filenames
'baseDir' => '', // See UploaderComponent::$baseDir
'uploadDir' => 'files/uploads/', // See UploaderComponent::$uploadDir
'dbColumn' => 'imgPath', // The database column name to save the path to
'maxNameLength' => 60, // Max file name length
'overwrite' => false, // Overwrite file with same name if it exists
'stopSave' => true, // Stop the model save() if upload fails
'allowEmpty' => true, // Allow an empty file upload to continue
'transforms' => array( // What transformations to do on images: scale, resize, etc
array(
'method' => 'resize',
'width' => 50,
'height' => 50,
'append' => '_thumb',
'dbColumn' => 'imgPathThumb',
)
)
)
)
This is the photo admin edit view form:
<?php echo $this->Html->script('ckeditor/ckeditor');?>
<?php echo $this->Form->create('Photo', array('type' => 'file'));?>
<fieldset>
<legend><?php echo __('Admin Edit Photo'); ?></legend>
<?php
echo $this->Form->input('title');
echo $this->Form->input('caption', array('class'=>'ckeditor'));
echo $this->Form->input('imgPath', array('type' => 'file'));
echo $this->Form->input('alt_tag');
echo $this->Form->input('type', array( 'label' => 'Choose a type of photo', 'options' => array(
'gallery'=>'gallery',
'news'=>'news',
'post'=>'post',
)));
echo $this->Form->input('active', array( 'label' => 'Make active', 'options' => array('yes'=>'yes','no'=>'no' )));
echo $this->Form->input('gallery_id');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
This is the controller admin edit code:
public function admin_edit($id = null) {
$this->layout = 'admin';
if (!$this->Photo->exists($id)) {
throw new NotFoundException(__('Invalid photo'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->Photo->save($this->request->data)) {
$this->Session->setFlash(__('The photo has been saved.'), 'success');
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The photo could not be saved. Please, try again.'), 'error');
}
} else {
$options = array('conditions' => array('Photo.' . $this->Photo->primaryKey => $id));
$this->request->data = $this->Photo->find('first', $options);
}
$galleries = $this->Photo->Gallery->find('list');
$this->set(compact('galleries'));
}
Have I overlooked something obvious?
Cheers, Paul
When You editing record, You must set ID of this record.
Add to form $this->Form->input('id') or set ID in controller before save() action
I'm googling high and low on this. I'm not sure where i went wrong cause I don't get any errors.
i have 3 tables:
MOVIES - id, title, genre, etc
GENRES - id, genre
GENRES_MOVIES - movie_id, genre_id
Movie model:
public $hasAndBelongsToMany = array(
'Genre' => array(
'className' => 'Genre',
'joinTable' => 'genres_movies',
'foreignKey' => 'movie_id',
'associationForeignKey' => 'genre_id'
)
);
View:
echo $this->Form->create('Movie', array('controller' => 'movies', 'action' => 'add', 'type' => 'file'));
echo $this->Form->input('title');
echo $this->Form->input('description', array('type' => 'textarea');
echo $this->Form->input('imdb_url');
echo $this->Form->year('release_year', 1900, date('Y'));
echo $this->Form->input('length', array('type' => 'number'));
echo $this->Form->input('genre', array('type'=>'select', 'multiple'=>'checkbox', 'options'=> $genres));
echo $this->Form->input('image', array('type' => 'file'));
echo $this->Form->button('Submit');
MoviesController:
public function add()
{
/* for populating checkbox */
$this->set('genres', $this->Movie->Genre->find('list', array('fields' => array('Genre.id', 'Genre.genre'))));
if($this->request->is('post'))
{
$data_movie = array(
'title' => $this->request->data['Movie']['title'],
'description' => $this->request->data['Movie']['description'],
'imdb_url' => $this->request->data['Movie']['imdb_url'],
'release_year' => (int)$this->request->data['Movie']['release_year']['year'],
'length' => (int)$this->request->data['Movie']['length'],
'user_id' => (int)$this->Auth->user('id')
);
$data_genre = array('Genre' => array());
foreach($this->request->data['Movie']['genre'] as $genre)
array_push($data_genre['Genre'], (int)$genre);
$data = array('Movie' => $data_movie, 'Genre' => $data_genre);
$this->Movie->create();
if($this->Movie->save($data)
{
echo 'success';
}
}
}
So, why did I bother setting up data manually for saving in the movieController, it is because the tutorials are telling me data should be organised like it is now (before that it looked a little different.. so i tried and this is what i have now (it looks ok to me)
http://s10.postimg.org/ikewszo95/Untitled_1.jpg
you can see the form here http://marko-stimac.iz.hr/temp/movies/movies/add (although submit wont work, i guess it is because of the Auth component not letting non-registered users)
hm any help would be greeatly appreciated :)
EDIT - updated controller
public function add()
{
$this->set('genres', $this->Movie->Genre->find('list', array('fields' => array('Genre.id', 'Genre.genre'))));
if($this->request->is('post'))
{
($this->Movie->saveAssociated($this->request->data))
{
$this->redirect('/');
$this->Session->setFlash('Success.');
}
}
}
Don't modify the data, that is, get rid of these lines
$data_genre = array('Genre' => array());
foreach($this->request->data['Movie']['genre'] as $genre)
array_push($data_genre['Genre'], (int)$genre);
$data = array('Movie' => $data_movie, 'Genre' => $data_genre);
$this->Movie->create();
And save your data using
if ($this->Movie->saveAssociated($this->request->data) {
...
EDIT
Modify your form, change this
echo $this->Form->input('genre', array('type'=>'select', 'multiple'=>'checkbox', 'options'=> $genres));
to this
echo $this->Form->input('Genre', array('type'=>'select', 'multiple'=>'checkbox', 'options'=> $genres));
I'd like to add a select box for searching with the CakeDC Search Plugin. IE:
<select name="field">
<option value="email">Search By Email</option>
<option value="first_name">Search By First Name</option>
</select>
Currently what I have in my VIEW is:
echo $this->Form->create('User', array(
'url' => array_merge(array('action' => 'index'), $this->params['pass'])
));
echo $this->Form->input('email', array('div' => false, 'empty' => true));
echo $this->Form->input('first_name', array('div' => false, 'empty' => true));
This works just fine this way, but I'd like to avoid the multiple input boxes and simplify it with a select box. I could hard it (take the value from the select box and combine it with the value from the input box), but there has to be another way to do it...
Here is my User Module:
public $filterArgs = array(
'email' => array('type' => 'like'),
'first_name' => array('type' => 'like')
);
And this is my Controller:
public function index() {
$this->Prg->commonProcess();
$this->paginate['conditions'] = $this->User->parseCriteria($this->passedArgs);
$this->set('users', $this->paginate());
}
i think you are looking for
echo $this->Form->input('search', array('div' => false, 'empty' => true));
and
public $filterArgs = array(
'search' => array('type' => 'like', 'field'=>array('email', 'first_name')),
);
and
public $presetVars = true;
but you would lose the "AND" of the two inputs in favor of an OR (this is less powerful).
if thats ok for you, this would be the way.
help me to fix isPut or isPost for save logic, in the following code i can view the data in the from, but when i am trying to save it its not working, i have tried ispost and isput logic both are not working. i think problem is with controller sections not with view
here is view of my form,
<?php
echo $this->Form->create('Role',array('url'=>array('controller'=>'Organisations','action' => 'edit_profile'),'id' => 'role'));
echo $this->Form->input('RoleLanguage.rolename',array('label'=>'Profile Name:','id'=>'rolename'));
$options = array('A' => 'Approve', 'P' => 'Pending', 'D' => 'Delete');
echo $this->Form->input('Role.status', array(
'options'=>$options,
'empty' => false,
'label'=>'Status',
'style'=>'width:100px',
'id'=>'status'
));
$id= array('value' => $id);
//print_r($id);die();
echo $this->Form->hidden('rle_id', $id);
echo "<br>";
$options = array('R' => 'Role', 'P' => 'Position', 'T' => 'Team','C'=>'Core Strategic Profile');
echo $this->Form->input('Role.type', array(
'options'=>$options,
'empty' => false,
'label'=>'Type of Job Profile:',
'style'=>'width:100px',
'id'=>'type'
));
echo "<br>";
echo $this->Form->input('RoleLanguage.external_document_URL',array('label'=>'External Document URL:','id'=>'external_document_URL','type'=>'text'));
echo "<br>";
echo $this->Form->input('RoleLanguage.description', array('style'=>'width:420px','rows' => '5', 'cols' => '5','label'=>'Description','id'=>'description'));
?>
here is controller logic
function edit_profile($id=NULL)
{
$this->layout='Ajax';
//print_r($id);die();
$this->set('id',$id);
$this->Role->recursive = 0;
$this->Role->id = $id;
$language = $this->getLanguage('content');
$this->Role->unBindModel(array("hasMany" => array('RoleLanguage')));
$this->Role->bindModel(array("hasOne" => array('RoleLanguage'=> array('foreignKey' => 'rle_id', 'className' => 'RoleLanguage', 'type' => 'INNER', 'conditions' => array('RoleLanguage.language' => $language)))));
$this->data = $this->Role->read();
//print_r($this->data);die();
if ($this->RequestHandler->isPut())
{
$this->data=array(null);
$this->autoRender = false;
$acc_id = $this->activeUser['User']['acc_id'];
$this->data['Role']['acc_id'] = $acc_id;
unset($this->Role->RoleLanguage->validate['rle_id']);
print_r($this->data);die();
$this->Role->saveAll($this->data);
}
}
i am serializing data in another view from where i am calling the qbove view code for that is
$.ajax({
type: 'Put',
url: $('#role').attr('action'),
data: $('#role').serialize()
It could be that the data is failing the model validation test that occurs when you call saveAll.
Have you tried printing $this->Role->invalidFields() to see if there is anything there?