I'm trying to create an edit form using Lithium to edit some MongoDB data. My data (produced by another tool) looks like this:
{
"thing_a" : "value_a",
"thing_b" : "value_b",
"settings" :
{
"sub_thing_a" : ["sub_value_a", "sub_value_b"]
}
}
The problem I'm having is with the array 'sub_thing_a' in 'settings'. I need to display a text box for each value so I can edit them and save them back. The ultimate aim here is to use some jQuery to add/delete text boxes to/from the form and then values from the array - but for now I'm trying to just get a simple version working that will let me edit the values and save them away.
My model is really simple:
<?php
namespace app\models;
class Test extends \lithium\data\Model {
protected $_meta = array('source' => 'test');
}
?>
and the controller likewise:
<?php
namespace app\controllers;
use app\models\Test;
class TestsController extends \lithium\action\Controller {
public function index() {
$tests = Test::all();
return compact('tests');
}
public function edit($id=null) {
if(isset($id)) {
$test = Test::find($id);
} else {
$test = Test::create();
}
if ($this->request->data) {
if ($test->save($this->request->data)) {
$this->redirect('/tests/index');
}
}
return compact('test');
}
}
?>
Problems start with the edit form - As I have it now, it will display the values of my array, but the data does not get written correctly. Any clues as to how I should approach this? (Note: As I mentioned earlier, I will need to produce a dynamic version of this that allows me to add/delete text boxes to/from the form, so I do need to be able to take some sort of control of the helper - in case there is some really easy 'convention' way of doing this.)
edit.html.php:
<?=$this->form->create($test); ?>
<?=$this->form->field('thing_a'); ?>
<?php foreach ($test->settings->sub_thing_a as $i=>$elem): ?>
<?=$this->form->field('settings.sub_thing_a',array('label'=>'thing', 'value'=>$test->settings->sub_thing_a[$i]));?>
<?php endforeach; ?>
<?=$this->form->submit('save'); ?>
<?=$this->form->end(); ?>
and index.html.php (for completeness)
<?php foreach($tests as $test): ?>
<h2><?=$this->html->link($test->thing_a,'/tests/edit/'.$test->_id); ?></h2>
<?php foreach($test->settings->sub_thing_a as $item): ?>
<h4><?=$item ?></h4>
<?php endforeach; ?>
<?php endforeach; ?>
Ok, so in the end, it was (of course) quite simple. in the edit.html.php file we can simply write:
<?=$this->form->field('settings[sub_thing_a][]',array('value'=>$test->settings->sub_thing_a[$i]));?>
The settings[sub_thing_a][] creates the array containing an array of the string values from the form.
Related
I'm trying to make dropDownList in _form view.
This is the Controller part
public function actionCreate()
{
$modelCountry = Country::model()->findAll();
$this->render('create',array(
'model'=>$model,'modelCountry'=>$modelCountry,
));
}
Now in _form view I have a TextField which must be modified to dropDownList
<div class="row">
<?php echo $form->labelEx($model,'name_en'); ?>
<?php echo $form->textField($model,'name_en',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'name_en'); ?>
</div>
That means I must modify it to something like this
<?php echo $form->dropDownList($model,'name_en',array('!Variable!A!From_modelCountry!','!Variable!B!From_modelCountry!' )); ?>
I can use foreach loop and inside that loop create some DropDownList but maybe there is some better way to take data out of an array $modelCountry and put them straight to array of that dropDownList?
yes you can do that. In your controller you can write
$list=CHtml::listData($modelCountry,'id','name_en');
$this->render('create',array(
'model'=>$model,'modelCountry'=>$modelCountry,'list'=>$list
));
Now in your View you can write
<?php echo $form->dropDownList($model,'name_en',$list); ?>
You can use Chmlt::listData in your view but that should be a part of controller, thats what MVC is all about.
<?php echo $form->dropDownList($model,'name_en',CHtml::listData(Country::model()->findAll(),'id','name')); ?>
I want to make text area in cactiveform in yii dynamically. but I am getting error i.e. "Property "Verse.translation" is not defined"
I have translation_text field, not translation field in my db. Secondly $trans['translation_text'] display the verse translation but when i keep it in textArea it is giving error. as i have described.
I have a code.
<?php foreach($model->verseTranslations as $trans) { ?>
<?php $model->translation = $trans['translation_text']; ?>
<?php echo $form->textArea($model,'translation',array('rows'=>6, 'cols'=>50)); ?>
<?php } ?>
But i do not know how to keep value $trans['translation_text'] in textArea.
Any help will be appreciated.
Thanks
Do it like this :
<?php foreach($model->verseTranslations as $trans) { ?>
<?php echo $form->textArea($model,'translation',array('value'=>$trans['translation_text'],'rows'=>6, 'cols'=>50)); ?>
<?php } ?>
And in your model as RobM said earlier, but don't forget to add a validator in you Verse class for 'translation' attribute ! :
class Verse extends CActiveRecord
{
public $translation;
public function rules()
{
return array(
array(
'translation',
'safe',
'on'=>'',
),
//others validators here
);
}
}
Just replace the second parameter in $form->textArea with $trans['translation_text'], so that it becomes:
<?php echo $form->textArea($model, $trans['translation_text'], array('rows'=>6, 'cols'=>50)); ?>
The second parameter is the value of the textArea, so the value of any variable here will show up as the default value of the text area element.
Add translation property to Verse class in models
class Verse extends CActiveRecord
{
public $translation;
I am doing the tree tutorial and would like to display the data in a view and wrap it in html etc. I am new to Cake PHP and this has been a bit of a pain. Below is an example of what I've tried. In short, I figure I could assign the output to a variable using set. I am doing everything wrong.
Controller
<?php
class CategoriesController extends AppController {
public function index() {
$this->set('output', $this->Category->generateTreeList(null, null, null, ' '));
}
}
?>
View
<?php foreach ($output as $data): ?>
<div><?php echo $data['Category']['name']; ?></div>
<?php endforeach; ?>
<?php unset($data); ?>
unlike other find methonds, generateTreeList doesen't return a named array but a plain array with numeric indexes
try print_r($output) and you'll see how the array is formatted and how you can use it in your view
to show your data, in your foreach cicle you just have to do this
echo $data;
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);
I have a Profile model/controller in my cake app as well as an index.ctp view in /views/profiles. Now, when I go to add a column to my table that is already filled with data, and then add the corresponding code to the view to pick up this column's data, it just gives me an empty result.
My model:
<?php
class Profile extends AppModel
{
var $name = 'Profile';
}
?>
My controller:
<?php
class ProfilesController extends AppController
{
var $name = 'Profiles';
function index()
{
$this->set('profiles', $this->Profile->find('all'));
}
}
?>
My views printing (stripped down):
<?php foreach ($profiles as $profile): ?>
<?php echo $profile['Profile']['id']; ?>
<?php echo $profile['Profile']['username']; ?>
<?php echo $profile['Profile']['created']; ?>
<?php echo $profile['Profile']['thumbnail'];?>
<?php echo $profile['Profile']['account'];?>
<?php endforeach; ?>
Basically, the columns id, username, column, thumbnail always have been printing fine, but when I add a column called accountit returns no information (nothing prints, but no errors). Any suggestions?
I would delete the files in app/tmp/cache (but keep the directories).
For CakePHP 4, clearing tmp/cache/models worked for me.