Jump to content
Larry Ullman's Book Forums


  • Content Count

  • Joined

  • Last visited

  • Days Won


Philip last won the day on November 4 2013

Philip had the most liked content!

Community Reputation

5 Neutral

About Philip

  • Rank
  1. I got it working by using listdata in the end. 'filter' => CHtml::listData(CourseEcts::model()->findAll(), 'id', 'ects_points'), I had to create a model for CourseEcts points and now I get a dropdown with the ects points which filters perfectly. It's not the most elegant of solutions as the dropdown is not based on the data in the gridview, but thats a separate issue that I'll come back to later. Thanks for all your help and suggestions! :-)
  2. Hi Edward, I think I have solved half the problem anyway. I found an article here which helped. I've gotten filtering to work on the related columns by adding properties to the CoursePeriod model. For example, to get textfield filtering working on Course.course_name and Course.ects_points I added the following properties in the CoursePeriod model: public $search_ects_points; public $search_course_name; I then added them to the rules ... search_ects_points, search_course_name', 'safe', 'on'=>'search'), in the search method I added the following $criteria->compare('course.ects_points',$this->search_ects_points, true); $criteria->compare('course.course_name',$this->search_course_name, true); which means I can now do this in the view array( 'header' => 'ECTS', 'name' => 'search_ects_points', 'value' => '$data->course->ects_points', and it seems to work fine on both columns. What I am missing now is the dropdown on ects_points. I tried this: 'filter' => CHtml::dropDownList('Course[ects_points]', $model->search_ects_points, array( '5' => '5', '10' => '10'), array('empty' => 'All')), but it doesn't filter. I don't get an error and there is a dropdown filter with all, 5 and 10, but on selecting 5 or 10, the grid just refreshes. I'm sure I'm close and I'm kinda shooting in the dark, but I'll get there. If you have any ideas regarding this, feel free to post. I'll post my fix if I come up with it.
  3. Sorry, it can also be difficult to know how much to post without overwhelming the thread and I do appreciate your help! anyway as I've mentioned, I have two tables: CoursePeriod: id, course, term, year, start_date, end_date, other_non_important_logging_fields Course: course_id, course_name, department, course_level, ects_points CoursePeriod.course is a foreign key to Course.course_id My gridview is pulling from CoursePeriod and displays the following columns: Course.course_name, Course.course_level, CoursePeriod.CourseDates, Course.ects_points CourseDates comes from getCourseDates() in CoursePeriod, but I'm not concerned about filtering this. The only columns that have to be filter are the related columns with course_name as a textfield, course_level and ects_points as dropdowns. I hope that this makes more sense to you now. Thanks again for your help
  4. The thing is that I am actually able to display ects points and I can also filter them using at text field, it's just the dropdown that isn't working. so this works: array( 'header' => 'ECTS', 'name' => 'course', 'value' => '$data->course->ects_points', but this doesn't array( 'header' => 'ECTS', 'name' => 'course', 'value' => '$data->course->ects_points', 'filter' => CHtml::dropDownList('Course[ects_points]', $m->course->ects_points, array( 5 => 5, 10 => 10), array('empty' => 'All')), A course can have either 5 or 10 ects points which is why I want to filter courses using a dropdown. Hmmm I guess I'll have to give it a thorough look through to see if I am misunderstanding something with the relationships. I'm fairly new to Yii. :-)
  5. Thanks Edward, I think I am doing something wrong in my search() criteria and the name of the filter in gridview too. as a little back ground, my gridview is pulling from CoursePeriod, which has a foreign key in Course as basically courses are being reused every year. So CoursePeriod contains a course id call "course" which points to "course_id" in Course. I'd like to be able to add more information to the gridview such as course_name, ects_points and course level, all of which are contained in Course. I can get all the data to display using 'value'=>'$data->course->course_name' etc, but if I want to filter on each of these columns, I need to relate them back to Course somehow. At the moment I have the ects_points dropdown set up with 'name'=>'course', but this can't be correct, as what would I use for the others that are also related to Course? I would have thought 'name' should be something like 'course.ects_points' but this doesn't work. In my CoursePeriod search method I have the following: $criteria=new CDbCriteria; $criteria->with = 'course'; $criteria->compare('id',$this->id); $criteria->compare('course.ects_points',$this->course); ... // and so on I should note that when I say that the filtering works with ects_points without the 'filter' element, it works, but all the columns change slightly (become smaller) so there seems to be an error somewhere.
  6. Thanks Edward, It seems I must have made a mistake the first time around, as I got it working through using the tabular input tutorial. Basically my view looks something like this now: ... <?php foreach ($models as $i => $ccModel): ?> <div class="row"> <?php switch ($i) { case "c1p1": echo $form->labelEx($models[$i], $i); echo CHtml::activeDropDownList($models[$i], 'course', $data, array('name' => "CourseChoice[$i]", 'prompt' => 'Select A Course')); echo $form->error($models[$i], $i); break; case "c1p2": echo $form->labelEx($models[$i], $i); echo CHtml::activeDropDownList($models[$i], 'course', $data, array('name' => "CourseChoice[$i]", 'prompt' => 'Select A Course')); echo $form->error($models['c1p2'], $i); break; } ?> </div> <?php endforeach; ?> ... This works, though I managed to convince management that this is a horrible way to present the data, so I'm off the hook with it anyway! ;-) Thanks again
  7. Hi Edward My models Course and CoursePeriod have a One-To-Many relationship as defined in their relations: Course 'coursePeriods' => array(self::HAS_MANY, 'CoursePeriod', array('course' => 'course_id')), CoursePeriod 'course' => array(self::BELONGS_TO, 'Course', array('course' => 'course_id')), So basically one course can have many course periods. I think that the relations are ok, as it works fine when I don't explicitly set the filter, as I get a textfield which which filters when I enter 5 or 10. I get no records as expected if I put something else in.
  8. Hi guys In the book there is a tutorial showing how to create a filter in cgridview using a related model. This works great for me and I'm able to filter the list fine. However, in my instance, there can only ever be two things to filter '5' ECTS points and '10' ECTS points, so I'd rather have a dropdown menu. I've tried to implement it but I keep getting an error "Trying to get property of non-object" at $model->course->ects_points Here is the section in CGridView array( 'header' => 'ECTS', 'name' => 'course', 'value' => '$data->course->ects_points', 'filter' => CHtml::dropDownList('Course[ects_points]', $model->course->ects_points, array( 5 => 5, 10 => 10), array('empty' => 'All')), ), If I remove the filter, I get a textfield filter which works fine. Thanks
  9. Hi Edward Thank you for replying. I've come across that page while looking into this, but couldn't quite get it working. I'll give it another read and try again for safe measure. Thanks again
  10. Hi guys I've had this issue for a while now and I'm completely stuck. I've been reading the book and found the section on uploading multiple files and I'm just wondering how this could be adapted to my situation. I'm trying to use dropdown menus to insert course takes into the database. Basically a student can choose a 1st and 2nd choice course and on submit, 2 rows are inserted into the CourseChoices table. I can get the two rows inserted to the DB fine, but only if all the columns have been filled. Basically validation is not working at all and I'm at a loss at how to implement it. To get the dropdowns to insert propertly, I had to change their name attributes so that they did not clash and override each other. This is probably where I am going wrong somehow. I posted a question on stack overflow related this, but I was trying to do it with a CForm, which apparently is not possible with multiple instances of the same model. Here is the link to my question on stack overflow. http://stackoverflow.com/questions/19526599/changing-cform-dropdown-name-attribute-in-yii Here is what I've done so far: In the controller (I'm using Wizard Behavior, so this is in WizardController.php) $model = array(); $model['c1p1'] = new CourseChoice(); $model['c1p2'] = new CourseChoice(); if (isset($_POST['courses']) && !empty($_POST['courses'])) { $c1p1 = $model['c1p1']; $c1p2 = $model['c1p2']; $c1p1->course = $_POST['courses']['c1p1']; $c1p1->student_id = Yii::app()->user->id; $c1p1->year = 2014; $c1p1->priority = 1; $c1p1->status = "STNSU"; $c1p2->course = $_POST['courses']['c1p2']; $c1p2->student_id = Yii::app()->user->id; $c1p2->year = 2014; $c1p2->priority = 2; $c1p2->status = "STNSU"; foreach ($model as $i=>$ccModel) { if ($ccModel->validate()) { $ccModel->save(); // This is Wizard behavior related step $event->sender->save($ccModel->attributes); } } // Using Wizard behavior related to handle the step $event->handled = true; and then the view <div class="form"> <?php $form = $this->beginWidget('CActiveForm', array( 'id' => 'user-form', 'enableAjaxValidation' => false, )); /* * This should be in the CourseChoice model, but is here for testing * To generate the course lists, CoursePeriod contains a foreign key to Course * This is because sometimes a course will run one year, but not the following year * or perhaps with a dates. Records therefore need to be keep for archived applications */ $data = CHtml::listData(CoursePeriod::model()->with('course0')->findAll("year = 2014"), 'id', 'course0.course_name'); ?> <?php echo $form->errorSummary($model); ?> <fieldset> <legend>Course 1</legend> <div class="row"> <?php echo $form->labelEx($model['c1p1'], 'c1p1'); ?> <?php echo $form->dropDownList($model['c1p1'], 'course', $data, array('name' => 'courses[c1p1]', 'prompt' => 'Please Select A Course')); ?> <?php echo $form->error($model['c1p1'], 'c1p1'); ?> </div> <div class="row"> <?php echo $form->labelEx($model['c1p2'], 'c1p2'); ?> <?php echo $form->dropDownList($model['c1p2'], 'course', $data, array('name' => 'courses[c1p2]', 'prompt' => 'Please Select A Course')); ?> <?php echo $form->error($model['c1p2'], 'c1p2'); ?> </div> </fieldset> <div class="row buttons" id="buttons"> <?php echo CHtml::submitButton('Previous', array('name' => 'previous')); echo CHtml::submitButton('Next', array('name' => 'next')); echo CHtml::endForm(); ?> </div> <?php $this->endWidget(); ?> </div><!-- form --> I would then have to validate this in the CourseChoice model i.e., how I put a rules in when I have changed the name attribute of the dropdowns. For example, Priority 1 is required, but Priority 2 is not. Any ideas where I am going wrong?
  11. Ok I seem to have solved the issue for now, though I'm not sure if it is the correct 'Yii' way of doing things. What I did in the end was to create a private property in the the controller called $_modelData. Then I loaded the additional model in loadModel(), stored it in $_modelData and created a $modelData variable in the actionUpdate method. public function loadModel($id) { $model=Student::model()->findByPk($id); $this->_modelData = StudentData::model()->findByPk($id); // other stuff public function actionUpdate($id) { $model=$this->loadModel($id); $modelData = $this->_modelData; // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model); if(isset($_POST['StudentData'])) { $model->attributes=$_POST['Student']; $modelData->attributes=$_POST['StudentData']; if($model->save()) $this->redirect(array('view','id'=>$model->id)); } $this->render('update',array( 'model'=>$model, 'modelData'=>$modelData, )); } In the view I can then do the following which loads the data from the two tables fine. <div class="row"> <?php echo $form->labelEx($model,'some_column'); ?> <?php echo $form->textField($model,'some_column'); ?> <?php echo $form->error($model,'some_column'); ?> </div> <div class="row"> <?php echo $form->labelEx($modelData, 'other_column'); ?> <?php echo $form->textField($modelData, 'other_column') ?> <?php echo $form->error($modelData, 'other_column'); ?> </div> Its seems to be a more long-winded way of doing it compared to $model->data in the actionCreate method. Does this sound like a good solution? I haven't completely finished the actionUpdate method yet, so it doesn't actually update the two tables, but I'm sure I'll get that part working. thanks again Phil
  12. Hi again Just a little update and a further question regarding the post. So I've finally gotten around to updating the database and have now implemented single table inheritance. I basically followed the advice in the the link provided by Larry in the updated database chapter - Yii - class table inheritance. Previously I had person, employee, student and teacher tables, but now I have a single user table with a column storing the user type. I then have a separate table storing addition student data. In Yii I have a model called User and another called Student which inherits from User. This works great and solves my original problem of registering a new student which is done in the actionCreate() method by doing the following: $model=new Student; $model->data=new StudentData(); In the form I can then handle the additional student data by doing the following: <div class="row"> <?php echo $form->labelEx($model->data, 'date_of_birth'); ?> <?php echo $form->textField($model->data, 'date_of_birth') ?> <?php echo $form->error($model->data, 'date_of_birth'); ?> </div> This all works perfectly and I can create a new user which is set to the correct user type and if the user is a student, the student data table is correctly updated. So it's a good solution all around for me and thanks for the suggestion. I do have a quick question though. If I am to apply the same logic to the actionUpdate, the loadModel() function is of course used. So I thought I'd edit loadModel() to contain the following: $model=Student::model()->findByPk($id); $model->data=StudentData::model()->findByPk($id); But it doesn't seem to pick up the additional student data and Yii is complaining data is not defined. Am I doing something wrong here or do I have to create an additional loadModel() method to handle the additional table data? Any advice would be appreciated! Regards Phil
  13. Hi Antonio and Larry, Apologies for taking so long to get back, I'm away in a summer house with no wifi and very limited data coverage. But I'm dealing with the withdrawal symptoms. :-) Anyway, thank you very much for your replies. @Antonio, thank you for posting your table structure. It is actually very similar to what I am dealing with here. Having a single user table would be ideal, however I can understand why the tables are split up between person, student and employee, as the developer probably wanted to ensure that certain properties can only be assigned to students. Once I get back to the office, I'll have a look at breaking the student and employee tables down in to smaller tables. @Larry, great that there is an update to the book, which I'll download once I get to a more stable connection. It's been a great read so far with lots of hints and tips. Obviously I spent most time reading through the auth and auth chapter, trying to think how I can apply it to my structure. I'll just play around with the framework and see how it goes. Thanks a million for the suggestions! Regards Phil
  14. Hi all, Just wondering if anybody would have a suggestion for this. I'm new to Yii but have been coding in PHP for quite some time. I've been tasked to rewrite an old application in work which has become a mess over time. It is written in loosely object oriented PHP and uses MySQL. I've recently bought the Yii Book and is seems very good so far. I do have one question and I've tried searching around for similar questions, but can't seem to get a definite answer. Basically the database is set up so that there is 'person' table which includes person_id, names and dates etc. Then there are two other tables called student and employee. Basically the PHP classes for those tables inherit from Person, as Student and Employee are substantially different. In the book (I'm at the chapter about models) Larry mentions having a user table, which greatly simplifies registration and login. However with my applications setup, the person_id in person is the same as either student_id in student or employee_id in employee. Registration is done by using PDO lastInsertID to get the person_id and use that for registering either a new student or new employee. So my question is, with this scenario, how would you recommend that I work with the person and student/employee models in Yii? Any advice would be appreciated! Regards Phil
  • Create New...