I'm having problems with my forms redirection for a specific controller. In my database table it called lists_acciones.
Model :
<?php
App::uses('AppModel', 'Model');
App::uses('CakeSession', 'Model/Datasource');
/**
* ListAccione Model
*
*/
class ListAccione extends AppModel {
public $useTable = 'lists_acciones';
Controller
<?php
App::uses('AppController', 'Controller');
/**
* ListsAcciones Controller
*
* #property Menu $Menu
*/
class ListsAccioneController extends AppController {
I can access any function from my controller and the controller is the url listsAccione
Now he was creating a form, then click the go to the index view but the controller that comes is lists_acciones
echo $this->Form->create('ListsAccione', array(
'action' => 'index',
'class' => 'form_center',
'id'=>'formulario_busqueda',
'inputDefaults' => array(
'label' => false,
'div' => false,
# define error defaults for the form
'error' => array(
'wrap' => 'span',
'class' => 'my-error-class'
)
)
));
From Javascript
var url = "<?php echo $this->Html->url(array(
'controller' => 'listsAccione',
'action' => 'index',
'admin'=>true));?>/page:"+pagina;
$('#formulario_busqueda').attr('action',url); //this works
I found the solution in the documentation CakePHP
'url' => ['controller' => 'listsAccione', 'action' => 'index'],
Related
Key question is, does the \yii\widgets\ListView actually support filters with Pjax, like it's \yii\widgets\GridView counterpart? Here's what I have tried that has led to a duplicate url params issue:
I have a Gii-created search model with a custom param, $userRoleFilter:
<?php
namespace common\models;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use yii\rbac\Item;
/**
* UserSearch represents the model behind the search form of `common\models\User`.
*/
class UserSearch extends User
{
public $userRoleFilter = null;
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['id', 'flags', 'confirmed_at', 'blocked_at', 'updated_at', 'created_at', 'last_login_at', 'auth_tf_enabled', 'password_changed_at', 'gdpr_consent', 'gdpr_consent_date', 'gdpr_deleted'], 'integer'],
[['username', 'email', 'password_hash', 'auth_key', 'unconfirmed_email', 'registration_ip', 'last_login_ip', 'auth_tf_key', 'userRoleFilter'], 'safe'],
];
}
/**
* {#inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = User::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 20,
],
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'flags' => $this->flags,
'confirmed_at' => $this->confirmed_at,
'blocked_at' => $this->blocked_at,
'updated_at' => $this->updated_at,
'created_at' => $this->created_at,
'last_login_at' => $this->last_login_at,
'auth_tf_enabled' => $this->auth_tf_enabled,
'password_changed_at' => $this->password_changed_at,
'gdpr_consent' => $this->gdpr_consent,
'gdpr_consent_date' => $this->gdpr_consent_date,
'gdpr_deleted' => $this->gdpr_deleted,
]);
$query->andFilterWhere(['like', 'username', $this->username])
->andFilterWhere(['like', 'email', $this->email])
->andFilterWhere(['like', 'password_hash', $this->password_hash])
->andFilterWhere(['like', 'auth_key', $this->auth_key])
->andFilterWhere(['like', 'unconfirmed_email', $this->unconfirmed_email])
->andFilterWhere(['like', 'registration_ip', $this->registration_ip])
->andFilterWhere(['like', 'last_login_ip', $this->last_login_ip])
->andFilterWhere(['like', 'auth_tf_key', $this->auth_tf_key]);
if (!empty($params['UserSearch']['userRoleFilter'])) {
$userRoleFilter = $params['UserSearch']['userRoleFilter'];
// inner join to the user role items to filter by assigned role
$query->alias('u')
->innerJoin(
'auth_assignment AS aa',
'u.id = aa.user_id AND aa.item_name = :roleName',
['roleName' => $userRoleFilter]
)
->leftJoin(
'auth_item AS ai',
'aa.item_name = ai.name AND ai.type = :typeRole',
['typeRole' => Item::TYPE_ROLE]
);
}
return $dataProvider;
}
}
Controller method:
/**
* Displays pricing calculation & data exports index.
*
* #return string
*/
public function actionDisplayUsers()
{
$searchModel = new UserSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('display-users', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
And manually wrapped my custom yii\bootstrap\ActiveForm in the Pjax tags:
<?php
/* #var $this yii\web\View */
/* #var $searchModel common\models\UserSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
use common\components\rbac\UserManager;
use yii\bootstrap\ActiveForm;
use yii\widgets\ListView;
use yii\widgets\Pjax;
$this->title = Yii::t('app', 'Display Users');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-display-users">
<div class="body-content">
<h1><?= $this->title ?></h1>
<?php Pjax::begin([
'options' => [
'id' => 'site-display-users-pjax-container',
],
'enablePushState' => true,
'enableReplaceState' => false,
]); ?>
<div class="well center-block meta-control">
<?php $form = ActiveForm::begin([
'id' => 'displayUsersForm',
'method' => 'get',
'options' => [
'data-pjax' => 1,
],
]); ?>
<div class="row row-grid">
<div class="col-xs-6">
<?=
$form
->field($searchModel, 'userRoleFilter')
->dropDownList(UserManager::getAvailableRoles(), [
'prompt' => 'Select User Role',
'id' => 'userRoleFilter',
])
?>
</div>
<div class="col-xs-6">
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
<div class="row">
<div class="col-lg-12">
<?php
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_display-user',
'viewParams' => [
// add params to pass into view here
],
]);
?>
</div>
</div>
<?php Pjax::end(); ?>
</div>
</div>
This works fine and filters the users in the ListView according to the selected role. But it is creating a duplicate url param after each time the filter is changed:
/site/display-users
/site/display-users?UserSearch%5BuserRoleFilter%5D=admin
/site/display-users?UserSearch%5BuserRoleFilter%5D=admin&UserSearch%5BuserRoleFilter%5D=role-importer-user
/site/display-users?UserSearch%5BuserRoleFilter%5D=admin&UserSearch%5BuserRoleFilter%5D=role-importer-user&UserSearch%5BuserRoleFilter%5D=admin
and so on...
I know that I can set the Pjax enablePushState and enableReplaceState values to false and then it does not keep creating history items and modifying the url in the browser, but just sends the same ever-lengthening url in the ajax request...
What can be done? Is there a better way to handle this? A setting I am missing to stop this duplication of get param keys stacking up in the url?
Found out the solution... turns out that the ActiveForm form action parameter needs to be explicitly defined so that this URI is used for each form submission rather than relying on the URL from the address bar.
<?php $form = ActiveForm::begin([
'id' => 'displayUsersForm',
'method' => 'get',
'action' => Url::to(['site/display-users']),
'options' => [
'data-pjax' => 1,
],
]); ?>
See here for more details.
I'm working with Drupal 8 and I have custom ajax form it works fine when I test it using [Ajax htmlCommands]. but now I want to send the data to the javascript file to show it in a div and do some other things.
what I did is create js file under themes/custom/myform/assets/js/simple-form.js but nothing shows in the console when the element clicked.
Drupal.behaviors.simple_form = function(context) {
$('.btn-primary').click(function() {
console.log('clicked');
});
};
and add it to themes/custom/myform/myform.libraries.yml
simple-form-js:
js:
assets/js/simple-form.js: {}
my custom form
modules/custom/my_module/src/Form/SimpleForm.php
<?php
namespace Drupal\my_module\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
/**
* Our simple form class.
*/
class SimpleForm extends FormBase {
/**
* {#inheritdoc}
*/
public function getFormId() {
return 'my_module';
}
/**
* {#inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
//$form = parent::buildForm($form, $form_state);
$form['#theme'] = 'simple_form';
$form['massage'] = [
'#type' => 'markup',
'#markup' => '<div class="result_message"></div>',
];
$form['number_1'] = [
'#type' => 'textfield',
'#title' => $this->t('number 1'),
'#attributes' => ['class' => ['form-control ml-sm-2 w-100']],
'#required' => TRUE,
];
$form['number_2'] = [
'#type' => 'textfield',
'#title' => $this->t('number one'),
'#attributes' => ['class' => ['form-control ml-sm-2 w-100']],
'#required' => TRUE,
];
$form['actions'] = [
'#type' => 'button',
'#value' => $this->t('Calculate'),
'#attributes' => ['onclick'=>'return false;','class' => ['mt-3 btn btn-primary btn-me2']],
'#attached' => [
'library'=>[
'simple-form',
]
],
'#ajax' => [
'callback' => '::setMessage',
]
];
return $form;
}
public function setMessage(array &$form, FormStateInterface $form_state) {
$response = new AjaxResponse();
$letter = $form_state->getValue('number_1');
$code = $form_state->getValue('number_2');
$fetchUrl = 'http://example.com/api';
$responseAPI = \Drupal::httpClient()->get($fetchUrl, array('headers' => array('Accept' => 'text/plain')));
$data = (string) $responseAPI->getBody();
//drupal_set_message($data);
$response->addCommand(
new HtmlCommand(
'.result_message',
'<div class="my_top_message">' . $this->t('The result is #result', ['#result' => ($data)])
)
);
return $response;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {#inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
}
}
and themes/custom/myform/myform.theme
if($route_namee=="my_module.simple_form"){
$variables['#attached']['library'][] = 'myform/simple-form-css';
$variables['#attached']['library'][] = 'myform/simple-form-js';
}
You can use HOOK_form_alter to attach libraries
*/**
* Implements hook_form_alter().
*/
function my_module_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
if($form_id == "my_module") {
$form['#attached']['library'][] = 'myform/simple-form-js';
$form['#attached']['library'][] = 'myform/simple-form-css';
$form['#attached']['drupalSettings']['my_module']['variable'] = 'Your Custom values to JS';
return $form;
}
}
What you are looking for is a ajaxCommand and not a behavior.
Create a custom ajaxCommand and pass your variables to it when creating the ajax response.
Here is help https://weknowinc.com/blog/creating-custom-ajax-command-drupal-8
And get Inspired with how Drupal Cores InvokeCommand is working
To attach library you dont need theme or module files for example :
$form['#attached']['library'][] = 'core/drupal.dialog.ajax';
is enough to attach a library in your case you should call your js file like :
$form['#attached']['library'][] = 'simple-form-js';
Then files under your library will loaded with your form.
have multiple model on same form
I dont want to save data on both model but i just want to display one variable on view file
I have 2 tables
Organiser and Event
Organiser will log in and Create Event
Now there are few fields which are common in both tables
so when logged in user click on Create Event button i want to display address from Organiser table on the form
This is what i have done until now
which may not be the right approach
so let me know if that can be achieved any other simpler way
public function actionCreate()
{
$model = new Event();
$model2 = $this->findModel2(Yii::$app->user->id);
if ($model->load(Yii::$app->request->post())) {
if($_POST['User']['address'] == null)
{
$model->location = $model2->address;
}
else{
$model->location = $_POST['User']['address'];
}
$model->is_active = 1 ;
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'model2' => $model2
]);
}
}
protected function findModel2($id)
{
if (($model2 = User::findOne($id)) !== null) {
return $model2;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
And here is my _form.php code
<?php $form = ActiveForm::begin([
'options' => [
'id' => 'create-event-form'
]
]); ?>
<?= $form->field($model, 'interest_id')->dropDownList(
ArrayHelper::map(Areaintrest::find()->all(),'id','area_intrest'),
['prompt'=> 'Select Event Category']
) ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?php
if ($model->isNewRecord){
echo $form->field($model2,'address')->textInput(['class' => 'placepicker form-control'])->label('Location');
}
else
echo $form->field($model,'location')->textInput(['class' => 'placepicker form-control']);
?>
<di"form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-danger' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Now the problem here seems is that when it comes to saving part throws error saying unknown property address because that field doesnt exists in the database table Event
i just want that data to display it on the location field of my create form
so what should i do here
Here is the table structure
Organiser Event
organiser_id event_id
username organiser_id
clubname title
image location
email
firstname
lastname
address
Error page says something like this
Unknown Property – yii\base\UnknownPropertyException
Getting unknown property: common\models\Event::address
And here is my Event model
class Event extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'event';
}
public function rules()
{
return [
[['organiser_id', 'interest_id', 'title', 'location'], 'required'],
[['organiser_id', 'interest_id'], 'integer'],
[['title', 'location'], 'string', 'max' => 255],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'organiser_id' => 'Organiser ID',
'interest_id' => 'Event Type',
'title' => 'Event Title',
'location' => 'Location'
];
}
public function getOrganiser()
{
return $this->hasOne(User::className(), ['organiser_id' => 'organiser_id']);
}
}
Here is my User model represent Organiser table and model name in frontend model SignUp.php
class SignupForm extends Model
{
public $username;
public $address;
public $password;
public $password_repeat;
public function rules()
{
return [
['username', 'filter', 'filter' => 'trim'],
['username', 'required'],
['address', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
[['file'], 'file', 'extensions'=>'jpg, gif, png'],
['password', 'required'],
['password', 'string', 'min' => 6],
['password_repeat', 'compare', 'compareAttribute' => 'password'],
];
}
public function attributeLabels()
{
return [
'password_repeat' => 'Confirm Password',
'address' => 'Address',
'username' => 'Username',
];
}
public function signup()
{
if ($this->validate()) {
$user = new User();
$model = new SignupForm();
$user->address = $this->address;
$user->username = $this->username;
$user->setPassword($this->password);
$user->generateAuthKey();
if ($user->save()) {
return $user;
}
}
return null;
}
}
So i want to display the organiser.address on the Create event form in the field location
Hope you can understand it now
thank you
May be your function should look like
public function actionCreate()
{
$event= new Event();
$user= $this->findModel2(Yii::$app->user->id);
$event->location = $user->address;
if ($event->load(Yii::$app->request->post()) && $event->save()) {//active can set by default validator
return $this->redirect(['view', 'id' => $event->id]);
}
return $this->render('create', [
'event' => $event
]);
}
And in form you show location always. Then you can use it in update and create as well without ifs in view. Hope this will help you.
I am having a problem getting a custom query to alphabetize. It keeps defaulting to displaying in the order of the date it was posted. Below is my php function.
function json_info2() {
// The $_REQUEST contains all the data sent via ajax
if ( isset($_REQUEST) ) {
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// get values for all three drop-down menus
$status = $_REQUEST['status'];
$industry = $_REQUEST['services'];
$state = $_REQUEST['state'];
// array of values for each of the three drop-downs
$statusAll = array('complete','incomplete');
$industryAll = array('mining','textile','machinery');
$statesAll = array('SC','TX','WA');
// set $statusArray dependent on whether or not "all" is selected in the dropdown menu
if($status == "all") {
$statusArray = array( 'key' => 'status', 'value' => $statusAll, 'compare' => 'IN');
} else {
$statusArray = array( 'key' => 'status', 'value' => $status, 'compare' => '=');
}
if($industry == "all") {
$industryArray = array( 'key' => 'industry', 'value' => $industryAll, 'compare' => 'IN');
} else {
$industryArray = array( 'key' => 'industry', 'value' => $industry, 'compare' => '=');
}
if($state == "all") {
$stateArray = array( 'key' => 'state', 'value' => $statesAll, 'compare' => 'IN');
} else {
$stateArray = array( 'key' => 'state', 'value' => $state, 'compare' => '=');
}
$pages = array(
'post_type' => 'page',
'orderby' => 'title',
'order' => 'ASC',
'paged' => $paged,
'posts_per_page' => 5,
'meta_query' => array(
'relation' => 'AND',
$statusArray,
$industryArray,
$stateArray,
array(
'key' => '_wp_page_template',
'value' => 'template-individual-project.php',
'compare' => '='
)
)
);
// query results by page template
$my_query = new WP_Query($pages);
if($my_query->have_posts()) :
while($my_query->have_posts()) :
$my_query->the_post();
<li>
<?php the_title(); ?>
</li>
<?php
endwhile;endif;
wp_reset_query();
} // end of isset
?>
<?php
die();
}
add_action( 'wp_ajax_json_info2', 'json_info2' );
add_action( 'wp_ajax_nopriv_json_info2', 'json_info2' );
?>
This above function is called by the ajax function that follows:
function do_ajax() {
// Get values from all three dropdown menus
var state = $('#states').val();
var markets = $('#markets').val();
var services = $('#services').val();
$.ajax({
url: ajaxurl,
data: {
'action' : 'json_info2',
'state' : state,
'status' : markets,
'services' : services
},
success:function(moredata) {
// This outputs the result of the ajax request
$('#project-list').html( moredata );
$('#project-list').fadeIn();
}/*,
error: function(errorThrown){
var errorMsg = "No results match your criteria";
$('#project-list').html(errorMsg);
}*/
}); // end of ajax call
} // end of function do_ajax
Is there something simple that I'm missing here? I have a similar custom query on the page when it loads (although that initial load query doesn't have the select menu values as args), and they display in alphabetical order just fine. It's only after the ajax call to filter the list that they are no longer in order.
I have found the issue after googling the problem for quite a while. I read that some of the people who were having this problem found that their theme was using a plugin called Post Types Order. It overrides the ability to set the orderby arg.
I looked at the plugins, and sure enough, Post Types Order was there. Everything I read said that the problem could be solved by unchecking "auto sort" in the settings for the plugin. However, I did that, and orderby still didn't work. I had to completely deactivate the plugin to get orderby title to work.
I'm newbie with Yii.
I have a CGridview with a cutom dataprovider which takes a parameter $select:
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'beneficiary-grid',
'dataProvider' => $model->searchForVoucherAssignment($select),
'filter' => $model,
'columns' => array(
'id',
'registration_code',
'ar_name',
'en_name',
'family_member',
'main_income_source',
'combine_household',
array( 'class'=>'CCheckBoxColumn', 'value'=>'$data->id', 'selectableRows'=> '2', 'header' => 'check',
),
),
));
That parameter $select takes its values from dropdownlist:
$data = CHtml::listData(Distribution::model()->findAll(array("condition"=>"status_id = 2")), 'id', 'code');
$select = key($data);
echo CHtml::dropDownList(
'distribution_id',
$select, // selected item from the $data
$data,
array(
)
);
So I defined a script to update the CGridview depending on the value of dropdownlist
Yii::app()->clientScript->registerScript('sel_status', "
$('#selStatus').change(function() {
$.fn.yiiGridView.update('beneficiary-grid', {
data: $(this).serialize()
});
return false;
});
");
My model:
public function searchForVoucherAssignment ($distribution_id = 0) {
$criteria = new CDbCriteria;
if ($distribution_id != 0) {
$criteria->condition = "Custom Query...!!";
}
$criteria->compare('id', $this->id);
//Custom Criteria
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'pagination' => array(
'pageSize' => 20,
),
));
}
The problem is that the CGridview isn't changing where a value of the dropdownlist changed...
I think you have selected the wrong Id for the change event. The Id should be
$('#distribution_id').change(function() {