I found default settings in DatePicker won't take into account Julian dates (i.e. pre-1582 european dates) but haven't found a proper way to overcome this issue. Any suggestion?
I would probably implement Keith Woods Calendar for jQuery. It may not be as friendly to code with as the default date picker but assigning it to a $form->textInput() should be simple enough.
So by now DataPicker is unable to take into account any other calendar than Gregorian. Just for the record, I'm posting my solution using Keith Wood's world calendar datepicker:
1) Created web/calendars/ and unzipped calendars package into it.
2) Created asset bundle CalendarAsset.php into assets folder (I chose Julian/Gregorian (default) calendars and english/spanish localisation; you may want to choose from other languages and calendars):
<?php
namespace app\assets;
use yii\web\AssetBundle;
class CalendarAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'calendars/humanity.calendars.picker.css',
];
public $js = [
'calendars/jquery.min.js',
'calendars/jquery.calendars.js',
'calendars/jquery.calendars.plus.js',
'calendars/jquery.plugin.js',
'calendars/jquery.calendars.picker.js',
'calendars/jquery.calendars.julian.js',
'calendars/jquery.calendars.picker-es.js',
'calendars/jquery.calendars-es.js',
];
public $jsOptions = [
'position' => \yii\web\View::POS_HEAD,
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
?>
3) Then I added web/calendars/jquery.mycalendar.calendars.js to include some default settings, a calendar selector and the common implementation fully ripped from Keith Wood's demos:
$.calendarsPicker.setDefaults({
dateFormat: 'yyyy-mm-dd',
defaultDate: '1478-06-24',
yearRange: 'c-120:c+120',
});
$('#selectCalendar').change(function() {
var calendar = $.calendars.instance($(this).val(), 'es');
var convert = function(value) {
return (!value || typeof value != 'object' ? value :
calendar.fromJD(value.toJD()));
};
$('.is-calendarsPicker').each(function() {
var current = $(this).calendarsPicker('option');
$(this).calendarsPicker('option', {calendar: calendar,
onSelect: null, onChangeMonthYear: null,
defaultDate: convert(current.defaultDate),
minDate: convert(current.minDate),
maxDate: convert(current.maxDate),
}).
calendarsPicker('option', {
onSelect: current.onSelect,
onChangeMonthYear: current.onChangeMonthYear
});
});
});
4) Finally I brought it all into _form.php view:
<?php
use app\assets\CalendarAsset;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
// Load Keith Wood's JQuery stuff selected in CalendarAsset.php.
CalendarAsset::register($this);
// Load my calendar defaults and implementation.
$this->registerJsFile('calendars/jquery.mycalendar.calendars.js');
// Link one calendar instantiation to id = "popupDatepicker" with Julian and spanish as defaults.
$this->registerJs("$('#popupDatepicker').calendarsPicker({calendar: $.calendars.instance('julian', 'es')});");
?>
...........
<?php $form = ActiveForm::begin(); ?>
<?= Html::label(Yii::t('app', 'Calendario'), 'selectCalendar', ['class' => 'control-label']) ?>
<div class="form-group">
<?= Html::dropDownList(null, null, [
'julian' => Yii::t('app', 'Calendario juliano'),
'gregorian' => Yii::t('app', 'Calendario Gregoriano'),
], ['id' => 'selectCalendar', 'class' => 'form-control']) ?>
</div>
<?= $form->field($model, 'fecha')->textInput(['id' => 'popupDatepicker', 'placeholder' => Yii::t('app', 'aaaa-mm-dd')]); ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Crear') : Yii::t('app', 'Actualizar'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Hope it may be useful to someone.
Related
I recently set up the ability to tag posts on my site. I had everything working fine. Then as I was wrapping up I tested all my admin side forms again. The Add Tag form no longer does anything. It doesn't even flash an error or redirect after submission. The page just reloads at the same URL. The only changes to the site I have made since initial testing was move the forms to the admin side of the dev site. Here is some code to hopefully reveal what the mystery is. Also my edit tag form is doing similar thing. It has no flash message but redirects back to the index, like its supposed to but with no changes made to the tag. Ill include the edit code as well.
Add.ctp in src/Template/Admin/Tags/Add.ctp
<div class="tags form large-9 medium-8 columns content">
<?= $this->Form->create($tag) ?>
<div class="form-group">
<fieldset>
<h1 class="page-header">New Tag</h1>
<?php
echo $this->Form->input('name', ['class' => 'form-control']);
?>
</fieldset>
</div>
<?= $this->Form->button(__('Submit'), ['class' => 'btn btn-primary']) ?>
<?= $this->Form->end() ?>
</div>
Here is my Add funciton in my TagsController:
public function add()
{
$this->viewBuilder()->layout('admin');
$tag = $this->Tags->newEntity();
if ($this->request->is('post')) {
$tag = $this->Tags->patchEntity($tag, $this->request->data);
if ($this->Tags->save($tag)) {
$this->Flash->success(__('The tag has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The tag could not be saved. Please, try again.'));
}
$this->set(compact('tag'));
$this->set('_serialize', ['tag']);
}
Here is my Edit funciton in my TagsController:
public function edit($id = null)
{
$this->viewBuilder()->layout('admin');
$tag = $this->Tags->get($id, [
'contain' => []
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$tag = $this->Tags->patchEntity($tag, $this->request->data);
if ($this->Tags->save($tag)) {
$this->Flash->success(__('The tag has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The tag could not be saved. Please, try again.'));
}
$this->set(compact('tag'));
$this->set('_serialize', ['tag']);
}
Edit.ctp in src/Template/Admin/Tags/Edit.ctp
<div class="tags form large-9 medium-8 columns content">
<?= $this->Form->create($tag) ?>
<div class="form-group">
<fieldset>
<h1 class="page-header">Edit Tag</h1>
<?php
echo $this->Form->input('name', array('class' => 'form-control'));
?>
</fieldset>
</div>
<?= $this->Form->button(__('Submit'), ['class' => 'btn btn-primary']) ?>
<?= $this->Form->end() ?>
</div>
Just as a side note. I started getting errors when creating a new post as well.
General error: 1364 Field 'section_id' doesn't have a default value
I did go into my DB and give the field a default value. But then when I fill out the form for a new post again, the error just moves to the next table column. I am assuming they are some how related since they popped up at the same time and because tags and posts are related to each other.
TagsTable:
class TagsTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('tags');
$this->displayField('name');
$this->primaryKey('id');
$this->hasMany('PostsTags', [
'foreignKey' => 'tag_id'
]);
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->requirePresence('name', 'create')
->notEmpty('name');
return $validator;
}
}
Tags Entity:
class Tag extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* #var array
*/
protected $_accessible = [
'*' => false,
'id' => false
];
}
When I place <?php debug($tag); ?> into my add.ctp view this is the out put it gives me:
object(App\Model\Entity\Tag) {
'[new]' => true,
'[accessible]' => [],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Tags'
}
Again, in question always post debug pathEntity output, in your case debug($tag), also Tag Entity, your validation code, and how looks your db tags table.
Answer:
General error: 1364 Field 'section_id' doesn't have a default value
This means that you have not passed a value for this field.
You can change that table field to accept null or empty value and/or set default if not passed from application, or make validation in your TagsTable to be sure if submitted data valid before send to db.
After question updated:
protected $_accessible = [
'*' => false, <---- should be true
'id' => false
];
This means that all fields except id are accessible
CakePHP seems to be loading the plugin because I'm not getting any errors when loading from bootstrap, including the helper in the control and then using it in the view, but nothing happens to my <textarea></textarea> tags which I placed before and after the script in the view. I have also loaded jQuery. Any ideas on what might be wrong?
Controller:
public $helpers = ['TinyMCE.TinyMCE'];
View:
<textarea></textarea>
$this->TinyMCE->editor(array('theme' => 'advanced'));
<textarea></textarea>
HTML (view source, when the page is loaded):
<textarea>
</textarea>
<script>
//<![CDATA[
tinymce.init({
script : "/TinyMCE/js/tiny_mce/tiny_mce.js",
load_script : "1",
theme : "advanced"
});
//]]>
</script>
<textarea>
</textarea>
Bootstrap:
Plugin::load('TinyMCE', ['autoload' => true]);
Configure::write('TinyMCE.configs', array(
'advanced' => array(
'mode' => 'textareas',
'theme' => 'advanced')));
I also just noticed, when I pr($this->TinyMCE);
I get:
TinyMCE\View\Helper\TinyMCEHelper Object
(
[helpers] => Array
(
[0] => Html
)
[theme] =>
[plugin] =>
[fieldset] => Array
(
)
[tags] => Array
(
)
[implementedEvents] => Array
(
[View.beforeRender] => beforeRender
)
[_config] => Array
(
)
)
For some reason there is nothing in [theme] value, it should be - advanced. What am I doing wrong? Is something wrong with this line:
$this->TinyMCE->editor(array('theme' => 'advanced'));
Helper TinyMCE for CakePHP 2 with preset function.
TinyMCE
Download TinyMCE : http://www.tinymce.com/download/download.php
Copy /tinymce/jscripts/ tiny_mce folder to /app/webroot/js (like : /app/webroot/js/tiny_mce).
Controller
public $helpers = array('Tinymce');
Behavior
$this->Tinymce->input($Model.fieldName, $options = array(), $tinyoptions = array(), $preset = null)
Example
<div class="posts form">
<?php echo $this->Form->create('Post');?>
<fieldset>
<legend><?php echo __('Add Post'); ?></legend>
<?php
echo $this->Form->input('title');
echo $this->Tinymce->input('Post.content', array(
'label' => 'Content'
),array(
'language'=>'en'
),
'bbcode'
);
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
http://bakery.cakephp.org/2012/04/11/Helper-TinyMCE-for-CakePHP-2.html#
I am just starting Yii2 framework.
I want to create a dropdown list which is 1 to 10 and a submit button
Once select the option and click the button should go to next page to show the number I choose.
In my view file : index.php
use yii\widgets\ActiveForm;
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'QTY')->dropDownList(range(1, 10)) ?>
<?= Html::submitButton('Buy', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
Then when I go to the page it gave me 'Undefined variable: model' at dropdown list there.
What should I do to make it correct?
And what is the different between Html and CHtml?
Thanks.
this code is form.php not index.php.
because we can see, there are active form.
your model is undefined maybe you write the wrong code
this is example of controller index.php
public function actionIndex()
{
$searchModel = new PersediaanBarangSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Html and Chtml is the same
in Yii1=CHtml
in Yii2=Html
This is ment to be pagination? If yes use default functionality of the grid view.
This goes to controller:
$query = Post::find()->where(['status' => 1]);
$provider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'defaultOrder' => [
'created_at' => SORT_DESC,
'title' => SORT_ASC,
]
],
]);
return $this->render('path_to_view',['dataProvider'=>$provider]);
Read more
This goes to view:
GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
'id',
'name',
'created_at:datetime',
// ...
],
]);
Read more
Actually you model is not loaded, Please check below example.
public function actionIndex($id = Null)
{
$data=array();
$data['model'] = !empty($id) ? \app\models\YourModel::findOne($id) : new \app\models\YourModel();
return $this->render('index', $data);
}
I am using Yii2 and I want to create comment functionality on post using Pjax widget.
The comment windows displays all the existing comments for the post adding an edit button to the ones that belongs to the connected user in order to permit changes.
Under this list of comments,there is a form including a textarea and a submit button to allow comment creation.
Each time the user click on an already existing comment 's edit button, a form is displayed to allow update.
How all this actually runs and the trouble I meet:
I can update an existing comment an infinite number of times, and it is what I want.
If, just after refreshing the view post page, I enter a new comment, it
is correctly submitted. But I cannot enter an other one and I want to be able to post more than one. The second time, it appears that the POST contains the content of the comment but nothing
regarding the submit button. Thus I cannot recognize which button has
been clicked.
The same thing happens after I have changed an
existing comment i.e. I cannot create a new comment for the same
reason – nothing about the submit button in the POST.
My question
How comes the submit button is transmitted in the POST only if it is the first one used and it is the first time it is used after a refresh of the page?
Here are the relevant code parts
1-Controller
/**
* display a post
*#param integer $id
*
* return a view
*/
public function actionView ($id){
$post = $this->findModel($id);
$comment=$this->manageComment($post);
return $this->render('view', [
'post_model' => $post,
'comment_model' => $comment,
]);
}
/*
* deals with the post according to the submit value
* if submitted and return the comment under treatment
* otherwise – not submitted – return a new comment
*
*#param $post the post that holds the comments
*
* return a Comment model
*/
protected function manageComment($post)
{
$comment=new Comment;
if(isset($_POST['Comment']) )
{
switch ($_POST['Submit']) {
case 'create':
$comment->attributes=$_POST['Comment'];
if($post->addComment($comment,false))
{
//la création a réussi
if($comment->status==Comment::STATUS_PENDING)
Yii::$app->session->setFlash('success',
Yii::t('app','Thank you for your comment.
Your comment will be visible once it is approved.'));
//on renouvelle le commentaire pour éviter d'avoir
//un bouton update (mise à jour)
return new Comment;
}
break;
case 'update':
$comment=Comment:: find()
->where(['id' => $_POST['Comment']['id']])
->one();
if($comment->attributes=$_POST['Comment']){
if($post->addComment($comment,true))
{
//update successful
if($comment->status==Comment::STATUS_PENDING)
{Yii::$app->session->setFlash('success',
Yii::t('app','Thank you for your comment.
Your comment will be visible once it is approved.'));}
$comment= new Comment;
return $comment;
} else {
//la mise à jour a échoué
$comment= new Comment;
return $comment;
}
}else{echo'load failed'; exit();}
break;
case 'edit':
// echo $_POST['Comment']['id']; exit();
$comment->id = $_POST['Comment']['id'];
return $comment;
break;
default:
}
}
//creation successful
return $comment;
}
2-In Post view
<!--comment_model is passed by PostController-->
<?= $this->render('#app/views/comment/_create-form',
['model' => $comment_model, 'post' => $post_model]); ?>
3 - the _create-form view
<div class="comment-form">
<?php Pjax::begin([ ]);?>
<!-- this bloc must be part of the Pjax in order for the new
comment to appear immediately -->
<div class="comment">
<h4 ><?= Yii::t('app','Comments by users')?></h4>
<div class="comments">
<?php $comments= Comment::find()
->where (['post_id' => $post->id ])
->andWhere(['status' => true])
->all();
foreach($comments as $com){
$identity= User::findIdentity($com->user_id);
$firstname=$identity->firstname;
familyname=$identity->familyname;
$date= Utils::formatTimestamp($com->created_at);
$txt1 = Yii::t('app','Posted by ');
$txt2 = Yii::t('app',' on ');
$text_header =$txt1. $firstname.' '.$familyname.$txt2.$date;
//here we check that $model->id is defined an equal to $com->id
//to include edition form
if (isset($model->id) && ($model->id == $com->id) )//
{
// echo Yii::$app->user->identity->id. ' '.$com->user_id; exit();
echo $this->render(
'_one-comment',(['com' => $com,
'text_header' => $text_header,
'submit_btn' => false,
'with_edit_form' => true]));
} else
{
$submit_btn=false;
if (Yii::$app->user->identity->id == $com->user_id) $submit_btn=true; else $submit_btn=false;
echo $this->render('_one-comment',(['com' => $com, 'text_header' => $text_header, 'submit_btn' => $submit_btn,'with_edit_form' => false]));
}
}?>
</div>
<!--this div should be between Pjax::begin and Pjax::end otheswise it is not refreshed-->
<div id="system-messages" >
<?php foreach (Yii::$app->session->getAllFlashes() as $type => $message): ?>
<?php if (in_array($type, ['failure','success', 'danger', 'warning', 'info'])): ?>
<?= Alert::widget([
'options' => ['class' => ' alert-dismissible alert-'.$type],
'body' => $message
]) ?>
<?php endif ?>
<?php endforeach ?>
</div>
<?php
$form = ActiveForm::begin([
'options' => ['data' => ['pjax' => true]],//'id' => 'content-form'
// more ActiveForm options
]); ?>
<?= $form->field($model, 'content')
->label('Postez un nouveau commentaire')
->textarea(['rows' => 6]) ?>
<?= Html::submitButton('Create comment',
['content' => 'edit','name' =>'Submit','value' => 'create']) ?>
<?php
ActiveForm::end();?>
</div>
<?php Pjax::end()
?>
</div>
4 - the _one-comment view
<div class="one-comment">
<div class="comment-header">
<?php echo $text_header;?>
</div>
<div class="comment-text">
<?php echo $com->content;?>
</div>
<div class="comment-submit">
<?php
if ($with_edit_form)
{
// echo "with edit ".$com->id; exit();
echo $this->render('_update-one-comment',(['com' =>$com]));
} else
{
if($submit_btn){
$form = ActiveForm::begin([
'options' => [ 'data' => ['pjax' => true]],//'name' => 'one','id' => 'com-form-'.$com->id,
// more ActiveForm options
]); ?>
<?= $form->field($com, 'id')->hiddenInput()->label(false);?>
<div class="form-group">
<?= Html::submitButton('', [
'class' => 'glyphicon glyphicon-pencil sub-btn',
'content' => 'edit',
'name' =>'Submit','value' => 'edit']) ?>
</div>
<?php
ActiveForm::end();
}
}?>
</div>
</div>
5 the _update-one-comment form
//echo 'dans update-one-comment';print_r($com->toArray()); exit();
$form = ActiveForm::begin([
'options' => [ 'data' => ['pjax' => true]],//'name' => 'edit-one','id' => 'edit-com-form-'.$com->id,
// more ActiveForm options
]); ?>
<?= $form->field($com, 'id')->hiddenInput()->label(false);?>
<?= $form->field($com, 'created_at')->hiddenInput()->label(false);?>
<?= $form->field($com, 'updated_at')->hiddenInput()->label(false);?>
<?= $form->field($com, 'content')
->label('Mise à jour commentaire')
->textarea(['rows' => 6]) ?>
<div class="form-group">
<?= Html::submitButton($com->isNewRecord ?
Yii::t('app', 'Create comment') :
Yii::t('app', 'Update comment'), ['class' => $com->isNewRecord ?
'btn btn-success' :
'btn btn-primary','name' =>'Submit','value' => 'update']) ?>
</div>
<?php
ActiveForm::end();
?>
6- the Post model 's addComment()
public function addComment($comment, $up=false)
{
if(Yii::$app->params['commentNeedApproval'])
{$comment->status=Comment::STATUS_PENDING;}
else {$comment->status=Comment::STATUS_APPROVED;}
$comment->post_id=$this->id;
$comment->user_id=Yii::$app->user->identity->id;
if($up){
$test=$comment->update();
if($test) {//($comment->save(false)){
Yii::$app->session->setFlash('success',Yii::t(
'app','The comment has been succesfully updated.'));
return true;
}
Yii::$app->session->setFlash('failure',Yii::t(
'app','The comment could not be updatded.'));
} else
{ //création
if($comment->save()){
Yii::$app->session->setFlash('success',
Yii::t('app','The comment has been succesfully recorded.'));
return true;
}
Yii::$app->session->setFlash('failure',
Yii::t('app',$up.false.'The comment could not be recorded.'));
}
return false;
}
Why are you counting on the submit button name / value to figure out what you need to do?
$_POST['Comment']['id'] is a much better indicator of what needs to done. If it is there update otherwise create.
Also make sure the model does not allow editing of comments posted by others.
The model should not set flash messages, that is a job for the controller.
"I can update an existing comment an infinite number of times." of course you can, from what you told us there is nothing that would say you should not be able to. And you are not checking to prevent that.
As the submit button's value is not always transmitted in the post (it works with Chromium but not with Firefox), I solved my problem adding a hidden field in the forms and used it instead of the submit button's value.
I'm working on a Yii project with a database, containing a table, where almost all it's data is saved in a field as JSON (it's crazy, but it is so as it is):
id INTEGER
user_id INTEGER
data LONGTEXT
This "JSON field" data has following structure and contains inter alia an image:
{
"id":"1",
"foo":"bar",
...
"bat":{
"baz":"buz",
"name":"Joe Doe",
"my_picture":"iVBORw0KGgoAAAANSUhEUgAAAGQA...", <-- binary
...
}
}
Displaying it is no problem, but now I want to make the data ediable. My form looks like this:
<?php
$form=$this->beginWidget('CActiveForm', array(
'id' => 'insurance-form',
'htmlOptions' => array('enctype' => 'multipart/form-data'),
'enableAjaxValidation'=>false,
));
?>
<div class="row">
<?php echo $form->labelEx($model, 'provider_name'); ?>
<?php
echo $form->textField($model, 'data[provider][name]', array(
'size'=>60, 'maxlength'=>255, "autocomplete"=>"off"
));
?>
<?php echo $form->error($model, 'data[provider][name]'); ?>
</div>
It works.
I know, that for image upload I need fileField(...), but cannot find out, how to configure it in order to save the image directly to the database. How to do his?
view
<div class="row">
<?php echo $form->labelEx($model, 'provider_name'); ?>
<?php
echo $form->fileField($model, 'data[provider][name]', array());
?>
<?php echo $form->error($model, 'data[provider][name]'); ?>
</div>
controller
public function actionUpdate($id)
{
$model = $this->loadModel($id);
if(isset($_POST['External'])) {
$modelDataArray = $model->data;
// adding the image as string to the POSted data
if (isset($_FILES['MyModel']['name']['data']['provider']['picture'])) {
$_POST['MyModel']['data']['provider']['picture'] = base64_encode(
file_get_contents($_FILES['MyModel']['tmp_name']['data']['provider']['picture'])
);
}
$inputFieldData = $_POST['MyModel']['data'];
$updatedDataArray = array_replace_recursive($modelDataArray, $inputFieldData);
$model->attributes = $_POST['MyModel'];
$updatedDataJson = json_encode($updatedDataArray);
$model->setAttribute('data', $updatedDataJson);
if($model->save()) {
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('update', array(
'model' => $model,
));
}
CActiveRecord model
no special changes