رتبه موضوع:
  • 0 رای - 0 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
چطور از عناصر آرایه تعدادی چک باکس بسازم؟
#1
سلام استاد

من این آرایه رو دارم و میخوام عناصرش برای فرم مدل بصورت چک باکس نشون داده بشه.
$tags= $model->getTagsOptions();
<div class="row">
    <?php echo $form->labelEx($model,'tags',array('class'=>'col-sm-2 control-label')); ?>
    <div class="col-sm-4">
          <?php echo $form->checkBox($model,'tags',array('class'=>'form-control')); ?>
    </div>
    <div class="col-sm-4">
         <?php echo $form->error($model,'tags',array('class'=>'alert alert-danger')); ?>
     </div>
</div>
لطفا راهنمایی کنید.
متشکرم.
پاسخ
تشکر شده توسط:
#2
شما توی فیلد tags چطوری میخواین مقادیر رو ذخیره کنید؟ tags یه Relation هست یا فیلد معمولیه؟
پاسخ
تشکر شده توسط:
#3
tags یه فیلد معمولیه.
من این کارو انجام دادم:
<div class="row">
  <div class="col-sm-4">
       <?php echo $form->checkBoxList($model,'tags',$model->getTagsOptions()); ?>
  </div>
</div>
الآن چک باسهایی که ساخته شدن کدشون به این شکله:
کد:
<span id="AssignForm_tags">
    <input id="AssignForm_tags_0" type="checkbox" name="AssignForm[tags][]" value="1">
    <label for="AssignForm_tags_0">برچسب اول</label>
<br>
    <input id="AssignForm_tags_1" type="checkbox" name="AssignForm[tags][]" value="2">
    <label for="AssignForm_tags_1">برچسب دوم</label>
</span>
پاسخ
تشکر شده توسط:
#4
خوب شما چطوری میخواین توی یک فیلد معمولی مقدار چندتا TextBox تعریف کنید؟
پاسخ
تشکر شده توسط:
#5
فیلدهای tags و posts آرایه هستند و آیدیهای برچسبهای انتخاب شده برای اختصاص دادن به پستهای انتخاب شده را، به اکشن assign ارجاع میدن.
مدل AssignForm:
class AssignForm extends CFormModel
{
public $tags=array();
public $posts=array();

public function rules()
{
return array(
array('tags, posts', 'safe'),
);
}

public function attributeLabels()
{
return array(
'tags'=> 'برچسب ها',
           'posts'=> 'پست ها'
);
}

   public function getTagsOptions() {
       return  CHtml::listData(Tags::model()->findAll(
                   array(
                       'select'=> 'id, name',
                       'condition'=> 'confirm=1',
                       'order'=> 'name',
                   )
               ), 'id', 'name');
   }

   public function getPostsOptions() {
       return  CHtml::listData(Posts::model()->findAll(
                   array(
                       'select'=> 'id, title',
                       'condition'=> 'confirm=1',
                       'order'=> 'title',
                   )
               ), 'id', 'title');
   }

}
کد:
array
(
   'AssignForm' => array
   (
       'tags' => array
       (
           0 => '1'
           1 => '2'
       )
       'posts' => array
       (
           0 => '4'
           1 => '1'
           2 => '2'
           3 => '3'
       )
   )
)

حالا چطوری اینا رو اختصاص بدم؟  Ysmile
پاسخ
تشکر شده توسط:
#6
خوب شما بعد از اینکه مقادیر رو گرفتین، باید براساس هرکدوم از اونها یک رکورد توی جدول واسط بسازین. مثال:
foreach($model->tags as $tag) {
    $postTag = new Posttags;
    $postTag->post_id = $_GET['pid'];
    $postTag->tag_id = $tag;
    $postTag->save();
}

البته کد بالا خیلی کلیه و باید بر اساس سیستم خودتون تغییرش بدین.
پاسخ
تشکر شده توسط:
#7
این کد رو برا اختصاص برچسبها نوشتم. وقتی جدول posttag خالی و بدون مقدار است اختصاص برچسب بدرستی انجام میشه ولی وقتی جدول از قبل مقدارهایی داره، خطا میده.
public function actionAssign() {
       $model= new AssignForm;
       if(isset($_POST['AssignForm'])){
           //Tools::debug($_POST,true);

           $tags= $_POST['AssignForm']['tags'];
           $posts= $_POST['AssignForm']['posts'];
           $tagsCount=count($tags);
           $postsCount=count($posts);

           $oldPostTags= Posttag::model()->findAll(array('select'=>'post_id, tag_id'));

           if($oldPostTags){
               foreach($oldPostTags as $oldPostTag){
               //Tools::debug($oldPostTags,true);
                   for($i=0;$i<$tagsCount;$i++){
                       for($j=0;$j<$postsCount;$j++){
                           if($oldPostTag->tag_id!=(int)$tags[$i] && $oldPostTag->post_id!= (int)$posts[$j]){
                               $newPosttags= new Posttag;
                               $newPosttags->tag_id= (int)$tags[$i];
                               $newPosttags->post_id= (int)$posts[$j];
                               $newPosttags->confirm= 1;
                               $newPosttags->save();
                           }
                       }
                   }
               }
               Yii::app()->user->setFlash('message', 'برچسب های پست ها با موفقیت ثبت شدند.');
           }
           else{
               for($i=0;$i<$tagsCount;$i++){
                   for($j=0;$j<$postsCount;$j++){
                       $newPosttags= new Posttag;
                       $newPosttags->tag_id= (int)$tags[$i];
                       $newPosttags->post_id= (int)$posts[$j];
                       $newPosttags->confirm= 1;
                       $newPosttags->save();
                   }
               }
               Yii::app()->user->setFlash('message', 'برچسب های پست ها با موفقیت ثبت شدند.');
           }
       }
       $this->render('assign', compact('model'));
   }
خطا اینه:
کد:
خطای CDbCommand در اجرای SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicata du champ '1-2' pour la clef 'PRIMARY'. The SQL statement executed was: INSERT INTO `posttag` (`confirm`, `post_id`, `tag_id`) VALUES (:yp0, :yp1, :yp2)
چطوری چک کنم که اگه رکورد جدید با یکی از رکوردهای قبلی برابر بود، در جدول درج نشود؟
البته در کد بالا نوشتم ولی مشکل داره و میخوام بدونم روش بهتری وجود داره برای این کار؟
پاسخ
تشکر شده توسط:
#8
خوب این کلیدها از قبل وجود دارن. شما یا باید موقع تعریف تگها، همه تگهای قبلی رو حذف کنید و دوباره تگها رو ثبت کنید و یا قبل از ثبت تگ چک کنید اگه وجود نداشت، بعد ثبت کنید.
پاسخ
تشکر شده توسط:
#9
بصورت زیر قبل از اختصاص دادن، رکوردهای قبلی رو حذف کردم و برچسبهای جدید رو ثبت کردم.
$oldPostTags= Posttag::model()->findAll(array('select'=>'post_id, tag_id'));

           if($oldPostTags){
               foreach ($oldPostTags as $oldPostTag) {
                   $oldPostTag->delete();
               }
               for($i=0;$i<$tagsCount;$i++){
                   for($j=0;$j<$postsCount;$j++){
                       $newPosttags= new Posttag;
                       $newPosttags->tag_id= (int)$tags[$i];
                       $newPosttags->post_id= (int)$posts[$j];
                       $newPosttags->confirm= 1;
                       $newPosttags->save();
                   }
               }
               Yii::app()->user->setFlash('message', 'برچسب های پست ها با موفقیت ثبت شدند.');
           }
           else{
               for($i=0;$i<$tagsCount;$i++){
                   for($j=0;$j<$postsCount;$j++){
                       $newPosttags= new Posttag;
                       $newPosttags->tag_id= (int)$tags[$i];
                       $newPosttags->post_id= (int)$posts[$j];
                       $newPosttags->confirm= 1;
                       $newPosttags->save();
                   }
               }
               Yii::app()->user->setFlash('message', 'برچسب های پست ها با موفقیت ثبت شدند.');
           }
ولی میدونم که این راه حل کاملی نیست. بهتر بود قبل از درج چک میکردم.
متشکرم.
پاسخ
تشکر شده توسط:
#10
foreach($posts as $post_id => $post_value) {
    Posttag::model()->deleteAllByAttributes(compact('post_id'));
    foreach($tags as $tag_id => $tag_value) {
        $postTag = new Posttag;
        $postTag->post_id = $post_id;
        $postTag->tag_id = $tag_id;
        $postTag->confirm = 1;
        $postTag->save();
    }
}
Yii::app()->user->setFlash('message', 'برچسب های پست ها با موفقیت ثبت شدند.');
پاسخ
تشکر شده توسط: abdollah110110
#11
لطفا خطوط 1 و 2 رو توضیح بدین.
پاسخ
تشکر شده توسط:
#12
خط 1 که یه حلقه foreach برای تمام پستهایی که با چک باکس ارسال شدن، میسازه و خط 2 تمام تگهای اون post_id رو حذف میکنه.
توضیح: دو تا کد زیر مثل هم هستن:
compact('post_id')
array('post_id' => $post_id)
پاسخ
تشکر شده توسط: abdollah110110




کاربران در حال بازدید این موضوع: 2 مهمان