Yii framework CJUIautocomplete showing error - php

I am just newbie to the yii framework. Currently I have two tables
one for sales and other for stores
Sales table is looking like this
==============
sales
==============
id
store_id
store table is looking like this
==============
Stores
==============
id
store_name
store_location
Now in sales view form(_form.php) I have rendered both sales and stores.
In sales controller the code for action create is like this
public function actionCreate()
{
$model=new Sales;
$stores = new Stores;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Sales']$_POST['Stores']))
{
$model->attributes=$_POST['Sales'];
$stores->attributes = $_POST['Stores'];
$valid = $model->validate();
$valid = $stores->validate();
if($valid)
{
$stores->save(false);
$model->store_id = $stores->getPrimaryKey();
$model->save(false);
$this->redirect(array('view','id'=>$model->id));
}
}
$this->render('create',array(
'model'=>$model,
'stores' => $stores,
));
}
To get all the stores name in dropdown list I made my code like this
<div class="row">
<?php echo $form->labelEx($stores,'store_name'); ?>
<?php echo $form->dropDownList($stores,'store_name', CHtml::listData(Stores::model()->findAll(), 'store_name', 'store_name'), array('empty'=>'--Select--')) ?>
<?php echo $form->error($stores,'store_name'); ?>
</div>
But here I want the cjuiautocomplete field so that when someone will press any key then it will start to show the suggesions stores name. For that I just came through this link
and just like the docs I made the EAutoCompleteAction.php under protected/extension directory
Then I just made my controller code like this in sales controller
public function actions()
{
return array(
'aclist'=>array(
'class'=>'application.extensions.EAutoCompleteAction',
'model'=>'Stores', //My model's class name
'attribute'=>'store_name', //The attribute of the model i will search
),
);
}
and in view file of sales(_form.php) I made the code like this
<div class="row">
<?php echo $form->labelEx($stores,'store_name'); ?>
<?php
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'attribute'=>'store_name',
'model'=>$stores,
'sourceUrl'=>array('stores/store_name'),
'name'=>'store_name',
'options'=>array(
'minLength'=>'3',
),
'htmlOptions'=>array(
'size'=>45,
'maxlength'=>45,
),
)); ?>
After all when I am doing the search by keywords it is showing 404 error in console panel of firebug.
The requested search url in firebug was like this (ads was my search query in store name field)
http://localhost/WebApp/index.php?r=stores/store_name&term=ads
any one here for help?

You forgot to change action name from sample aclist into store_name:
public function actions()
{
return array(
'store_name'=>array( // << Array key is action name
'class'=>'application.extensions.EAutoCompleteAction',
'model'=>'Stores', //My model's class name
'attribute'=>'store_name', //The attribute of the model i will search
),
);
}

Related

yii, search for a value from textfield in database

I have this code on my view,
<div class="text-id-box">
<?php echo CHtml::textField($model,'id'); ?>
</div>
<div class="submit-box">
<?php echo CHtml::button('Search', array(
'submit' => array('SiteController/actionSearch',
array('id'=>$id)))); ?>
</div>
and my database:
id: varchar(8)
name: varchar(20)
location: varchar(50)
i wanna search id in my database, then return name, and location value. how to build its model and controller.
any help would be appreciated, thanks.
first generate the model using gii ref (http://www.yiiframework.com/doc/guide/1.1/en/topics.gii)
then you can add following function in your controller
public function actionSearch($id)
{
$model= new Yourmodel;
$model=Yourmodel::model()->findByPk($id);
//you will get the row for particular id
// and you can access it by $model->name $model->location
// render the required page and access to model object to get the name and location.
}

CGridView search not functioning when merged with create form

I have merged admin into create file by copying the gridview into create.php.
<?php $this->renderPartial('_form', array('model'=>$model)); ?>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'center-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'name',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
It is saving data but the search functionality of grid view is not functioning. Whereas, the same code of CGridView is functioning in admin.php.
here is my controller:
public function actionCreate()
{
$model=new Center;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Center']))
{
$model->attributes=$_POST['Center'];
if($model->save())
$this->redirect(array('create','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
After the model is saved you are redirecting to the same url i.e create but without the data from $_POST. The solution is to remove the call since you are essentially loading the same view, and would like to keep some of the data from the previous page.
public function actionCreate()
{
$model=new Center;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Center']))
{
$model->attributes=$_POST['Center'];
/*if($model->save())
$this->redirect(array('create','id'=>$model->id));*/
}
$this->render('create',array(
'model'=>$model,
));
}
HOWEVER
Reusing the same model for searching and inserting isn't a good approach since you will retain the data for the model that has been entered into the database (including its primary key(s)). A better one would be to use separate variables for the search and create and different name and id prefixes for fields of both forms. Then you can pass both variables into the views, and something entered into one field will not affect the other. You can also reuse the code in actionAdmin to refresh your grid via ajax without having to send the create form too.

How to send the request through POST and how to access attributes of the model?

I am a bit new to the Yii Framework. I am making a product selling website, which has 3 basic models
1. Users model containing the primary key id
2. Products model containing the primary key id
3. Orders model which is basically a mapping between the products and orders. It contains the fields product_id and user_id as foreign keys.
I have made a page where all the products are populated and the logged in user can click on a button on product box to order a particular product.
the code of the link is like this
<?php echo CHtml::link('Order Now',array('order',
'product_id'=>$model->id,
'user_id'=>Yii::app()->user->id)); ?>
(Q1) This is sending a GET request but I want to sent the details as post request. How to do this?
My default controller is the site controller. I have made an actionOrder method in this controller.
The code is:
if(Yii::app()->user->isGuest){
$this->redirect('login');
}else{
$model=new Orders;
if(isset($_POST['products_id']))
{
$model->attributes->products_id=$_POST['product_id'];
$model->attributes->users_id=Yii::app()->user->id;
if($model->save())
$this->redirect(array('index'));
}
$this->render('index');
}
But this code is showing bunch of errors. Also, (Q2) how can I put both products_id and users_id in a single array Orders so that I just have to write $_POST['orders']
Also, (Q3) how can I display a flash message after the save is successful?
Kindly help me to solve my 3 problems and sorry if you feel that the questions are too stupid.
Q1: If you want to use POST request, you're going to have to use a form of sorts, in this case the CActiveForm.
Controller:
public function actionOrder()
{
if(Yii::app()->user->isGuest)
$this->redirect('login');
else
{
$model=new Orders;
if(isset($_POST['Orders']))
{
$model->product_id=$_POST['Orders']['products_id'];
$model->users_id = Yii::app()->user->id;
if($model->save())
{
// Q3: set the flashmessage
Yii::app()->user->setFlash('ordered','The product has been ordered!');
$this->redirect(array('index'));
}
}
$this->render('index', array('model'=>$model)); //send the orders model to the view
}
}
View:
<!-- Q3: show the flash message if it's set -->
<?php if (Yii::app()->user->hasFlash('ordered')): ?>
<?php echo Yii::app()->user->getFlash('ordered'); ?>
<?php endif ?>
...
<?php $form=$this->beginWidget('CActiveForm', array('id'=>'order-form')); ?>
<?php echo $form->hiddenField($model,'products_id',array('value'=>$product->id)); ?> // please note the change of variable name
<?php echo CHtml::submitButton('Order Now'); ?>
<?php $this->endWidget(); ?>
Please note that I have changed the name of the product model variable $model to $product, because we will be using $model for the Orders model for the form.
Q2: In this case I set the users_id value in the controller, so $_POST['Orders'] only contains the value for products_id. In yii you can also mass assign your attributes with:
$model->attributes = $_POST['Orders']
Which basicly means $_POST['Orders'] is already an associative array containing the attribute names and values that are in your form.
Q3: The code shows you how to set and show a flash message after an order is succesfull.
First you have to declare forms send method, if you're using bootsrap it'll be like mine:
<?php $form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'action' => Yii::app()->createUrl($this->route),
'method' => 'post',
'id' => 'activity_timeRpt',
));
?>
Second if you want to send custom inputs, you have to specify, otherwise it'll be like
i'll be back to finish this
For your questions 1 and 2 I'd recomend you to use a CActiveForm class. For example
<?php $form = $this->beginWidget('CActiveForm', array(
'action' => 'you_action_here'
'method'=>'post' // this is optinal parameter, as 'post' is default value
)); ?>
<?php echo $form->textField($model,'product_id'); ?>
<?php echo $form->hiddenField($model,'user_id', array('value'=>Yii::app()->user->id)); ?>
<?php $this->endWidget(); ?>
where $model is instance of Orders class, passed by variables thru controller, or set in view file. After that you can use it in way you wanted $model->attributes = $_POST['orders'] in your action method.
For flash message you can use Yii->app()->user->setFlash('orderStatus', 'Successful'), before redirect( or render ) in your actionOrder. To show it:
<?php if(Yii::app()->user->hasFlash('orderStatus')):?>
<div class="info">
<?php echo Yii::app()->user->getFlash('orderStatus'); ?>
</div>
<?php endif; ?>

Change of data in the grid view based on change in a dropdown

I have 3 tables in mysql
city in which I have Cityid Cityname
labels in which I have
labelid langid and text
language table in which I have langid,
langname and enabled
Now the 3 tables are interrelated as cityname=labelid
text will hold the actual name
language will hold the language name
eg
City Table will be `
cityid=1, cityname=3000
cityid=2, cityname=3001
`
Labels Table will be
labelid =3000, langid=1, text=New York
labelid =3000, langid=23, text=New York in Chinese
labelid= 3001, langid=1, text= Mumbai
Language Table will be
`langid=1, lagname=english, enabled=1
langid=23, langname=chinese, enabled=1`
Now what I have achieved is to display the data of city in grid view and show a dropdown of all the languages whose enabled=1
What I want to do is change the content of the grid according to the language we have selected from the drop down.
So when Chinese is selected in the drop down then all the city names should appear in Chinese.
my view code is
$Labelcriteria = new CDbCriteria;
$Labelcriteria->condition = ("enabled=1");
$langarray= Language::model()->findAll($Labelcriteria);
$i=-1;
foreach ($langarray as $lang)
{
$i=$i+1;
$langName[$i]=$lang->langname;
}
//echo CHtml::dropDownList('select_box_name','select_value',$langName,array('onchange' => 'alert(1)',));
echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php
$this->renderPartial('_search',array('model'=>$model,));
?>
</div><!-- search-form -->
<?php
echo CHtml::dropDownList('select_box_name','select_value',$langName, array(
'onchange'=>'alert(1)',
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('cityController/dynamiccities'),
)
));
$this->widget('zii.widgets.grid.CGridView',
array('id'=>'city-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array('citycode', 'cityname',array('class'=>'CButtonColumn',),),));
?>
While my model is
public function search()
{
$criteria=new CDbCriteria;
$criteria->select = 't.citycode,lbl.text as cityname ';
$criteria->join = 'inner join labels lbl on t.cityname=lbl.labelid inner join language lng on lbl.langid=lng.langid';
$criteria->order = 'lbl.text ASC';
$criteria->condition=$someway_to_change_dynamically_using_dropdown;
$criteria->compare('citycode',$this->citycode,true);
$criteria->compare('cityname',$this->cityname,true);
// $criteria->compare('cityid',$this->cityid);
// $criteria->compare('seq_no',$this->seq_no);
// $criteria->compare('enable',$this->enable);
return new CActiveDataProvider($this, array('criteria'=>$criteria,));
}
Any help will be really appreciated
This is the controller action which renders the view file
public function Admin()
{
$model=new City();
$model->unsetAttributes(); // clear any default values
if(isset($_GET['City']))
$model->attributes=$_GET['City'];
$this->render('admin',array('model'=>$model));
}
OK I've tried to wrap my head around it and I think I have it.
You want to show all the city names in English by default, but have a drop down with all the available languages in. When the language is switched, show the city names in that language.
So what you need is to have the grid view filled with all the name pulled out using a parameter, specified by the drop down, but defaulting to English. Your most of the way there.
Your countries are pulled out here:
....dget('zii.widgets.grid.CGridView',
array('id'=>'city-grid',
'dataProvider'=>$model->search(),
....
I'm guessing you want to just show the code and the translated name within the grid view?
So the widget will become:
$this->widget('zii.widgets.grid.CGridView',
array('id'=>'city-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'citycode',
array(
'name'=>'Country',
'value'=>'$data->getLabel("'.$langId.'")',
),
array('class'=>'CButtonColumn')
),
));
On your city model you then need a method to get its langauge variant out based on the ID of the langauge, so place this into your model:
public function getLabel($id){
return $this->labels[$id]->text;
}
You'll also need the proper realationship for the labels for each cityname too. Because your below Yii 1.1.9 and your not pulling them down together (joining) we'll need a manual function to join a FK to a FK.
Add this to your city Model:
public function getLabels(){
return Labels::model()->findAll(array(
'condition'=>'labelid = :labelid',
'params'=>array(':labelid'=>$this->cityname)
));
}
and change its search function to:
public function search()
{
$criteria=new CDbCriteria;
$criteria->order = 'lbl.text ASC';
$criteria->compare('citycode',$this->citycode,true);
$criteria->compare('cityname',$this->cityname,true);
$criteria->compare('cityid',$this->cityid);
$criteria->compare('seq_no',$this->seq_no);
$criteria->compare('enable',$this->enable);
return new CActiveDataProvider($this, array('criteria'=>$criteria,));
}
Now you'll need to modify the action send the right variables into the view:
public function Admin($lang=1)
{
$model=new City();
//populate the filters
$model->attributes = $_GET['City'];
$this->render('admin',array('model'=>$model, 'langId'=>$lang));
}
Then the search form needs to show all the available countries, which you've got already pulled out here:
$Labelcriteria = new CDbCriteria;
$Labelcriteria->condition = ("enabled=1");
$langarray= Language::model()->findAll($Labelcriteria);
$i=-1;
foreach ($langarray as $lang)
{
$i=$i+1;
$langName[$i]=$lang->langname;
}
This could be replaced without any change to the results with:
$langarray = Language::model()->findAll(array('condition'=>'enabled=1','select'=>'langname'));
....I think
Either way, you have the countries there and are already popluating a drop down with them.
So all that should give you a view with the drop down of langauges and a grid view with the city names populated with English names by default, but if you pass the lang parameter with an ID it will show cities with that language.
How you implement the Javascript to actually update the grid view on Ajax will on the rest of your page layout, framework and splitting out some more views. But we can get into that another time.
You can use this for updating the content of a GridView with respect to the selection on a CHtml::dropDownList.
1)The js script is for capturing the onchange of the select:
Yii::app()->clientScript->registerScript('sel_status', "
$('#selStatus').change(function() {
//alert(this.value);
$.fn.yiiGridView.update('milestone-category-grid', {
data: $(this).serialize()
});
return false;
});
");
2)Code for the select:
$data = CHtml::listData(Status::model()->findAll('IsProcess=?',array(1)), 'ID', 'Description');
$select = key($data);
echo CHtml::dropDownList(
'dropDownStatus',
$select, // selected item from the $data
$data,
array(
'style'=>'margin-bottom:10px;',
'id'=>'selStatus',
)
);
3)For the gridview widget:
$this->widget('bootstrap.widgets.TbGridView',array(
'id'=>'milestone-category-grid',
'afterAjaxUpdate' => 'installSortable',
'enableSorting' => false,
'dataProvider'=>$model->search($select),
'rowCssClassExpression'=>'"items[]_{$data->ID}"',
'columns'=>array(
'Description',
),
)); ?>
4)In the Search function of your corresponding model the following code needs to capture the GET variable that is being passed, in this case it is dropDownStatus, the name given to the select (use Firebug, if necessary, to get the name of the variable being passed):
public function search($status=false)
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
if ($status!==false) {
$criteria->condition='StatusID=:StatusID';
$criteria->params=array('StatusID'=>$status);
}
if (isset($_GET['dropDownStatus'])) {
$criteria->condition='StatusID=:StatusID';
$criteria->params=array('StatusID'=>$_GET['dropDownStatus']);
$criteria->order='Position ASC';
}
...
Reference

Ascending Form numbers in Yii

In Yii I am doing a form in which the form has input fields for user details.I have made necessary input fields for all those fields.Where a user can submit all the values.Now I have a field where it will show the form number which will not be entered by user.It will be generated randomly with ascending order like
for the 1st form it will be like this FORM:001, For the second form it will be like this FORM:002 and it will go on.
Now I want that the form number will be like Form:001 so how to do that?HAny help and suggestions will be highly appriciable.
[UPDATED]
<div class="row">
<?php echo $form->labelEx($model,'id'); ?>
<?php echo Yii::app()->db->getLastInsertId();?>
<?php echo $form->error($model,'id'); ?>
</div>
This is the code for view > _form.php file.
and the result is ID 0
What you need is either of the following:
$maxFormId= Yii::app()->db->createCommand()
->select('max(id) as max')
->from('tbl_yourtable')
->queryScalar();
$yourFormId = "Form:".($maxFormId+ 1);
or alternatively run the following after the insert, and only display the form id then:
$yourFormId = "Form:".Yii::app()->db->getLastInsertId();
UPDATE:
public function actionCreate()
{
$model=new YourModel;
if(isset($_POST['YourForm']))
{
$model->attributes=$_POST['YourForm'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
On the above:
$this->redirect(array('view','id'=>$model->id));
automatically gives you the last ID inserted so you can just put the following in your view:
echo "Form:".$id;

Categories