I need to set dynamically
public function filterFields($fields, $context = null)
{
$return_date = $fields->return_date->value;
if(empty($return_date)) {
$fields->return_date->minDate = Carbon::now();
}
}
Not work!
Hmm, may be datetime widget is setting this restrictions at init time and filterfields is fired after that so it can not use new modified data.
to over come this we set config data before init , we use controller method formExtendFieldsBefore add this method to your controller
public function formExtendFieldsBefore($form) {
$form->fields['return_date']['minDate'] = \Carbon::now()->format('Y-m-d');
}
it should work, please check this and if face any issue please comment.
You should pay attention to your model's fields.yaml - Where have you defined the return_date field, is it in the primary or secondary tabs ?
Try :
public function formExtendFieldsBefore( $widget ) {
$widget->tabs['fields']['return_date']['minDate'] = Carbon::now()->format('Y-m-d');
}
Or
public function formExtendFieldsBefore( $widget ) {
$widget->secondaryTabs['fields']['return_date']['minDate'] = Carbon::now()->format('Y-m-d');
// notice here $widget->secondaryTabs Vs $widget->tabs
}
This should work, if it doesn't please share your fields.yaml file .
Related
I got a problem to save custom values for embededforms in root form.
I can actually edit a "manifestation" and i can add as much as i want "commande_wifi".
Everything is good saved.
I need to customize the process for every "commande_wifi" ( there is a 'puht' value depending on other values of the object() ). I have already lost a few hours only to do that.
save() is only called on the root form
That’s right! Only the root form has save() called. So if there’s other logic you want to run, you will want to override the saveEmbeddedForm method and call that code before. Oversimplification ahead: when you save a form with embedded forms, it calls $this->getObject()->save(), then it calls saveEmbeddedForms, which, for each embedded form, calls $form->saveEmbeddedForms() and then calls $form->getObject()->save(). This is critical to know, as it will save you a lot of headaches later on.
http://jmather.com/2011/01/29/6-things-to-know-about-embedded-forms-in-symfony/
I've tried to overwrite the saveembededForms() but fail at this point.
class manifestationForm extends BasemanifestationForm
{
public function configure()
{
$this->embedRelation('commande_wifi');
}
public function addNewFields($number){
$new_commandes = new BaseForm();
for($i=0; $i <= $number; $i+=1){
$commande = new Commande_wifi();
$commande->setManifestation($this->getObject());
$commande_form = new commande_wifiForm($commande);
$new_commandes->embedForm($i,$commande_form);
}
$this->embedForm('new', $new_commandes);
}
public function bind(array $taintedValues = null, array $taintedFiles = null){
$new_commandes = new BaseForm();
foreach($taintedValues['new'] as $key => $new_commande){
$commande = new Commande_wifi();
$commande->setManifestation($this->getObject());
$commande_form = new commande_wifiForm($commande);
$new_commandes->embedForm($key,$commande_form);
}
$this->embedForm('new',$new_commandes);
parent::bind($taintedValues, $taintedFiles);
}
public function saveEmbeddedForm($con = null, $forms = null)
{
if ($con === NULL)
{
$con = $this->getConnection();
}
if ($forms === NULL)
{
$forms = $this->getEmbeddedForms();
}
foreach ($forms as $form)
{
if ($form instanceof sfFormObject)
{
$form->saveEmbeddedForms($con);
$form->getObject()->setPuht(99);
$form->getObject()->save($con);
}
else
{
$this->saveEmbeddedForms($con, $form->getEmbeddedForms());
}
//$form->getObject()->setPuht(99)->save();
}
}
}
It's won ASAP i can access the embedForm Object().
Any suggestion?
I want to handle application feedback regarding, in this case, form validation.
To do this I check for model validation in controller, using
// VALIDATE
if ($this->Event->validates($this->data))
{
// SAVE
$this->Event->create();
if ($this->Event->saveAll($this->data, array('validate' => false)))
{
$this->Session->setFlash('Evenimentul a fost salvat!', 'flash_admin_success');
$this->redirect(array('action' => 'index', 'admin' => true));
} else {
$this->Session->setFlash('Evenimentul nu a putut fi salvat. Va rugam sa incercati din nou!', 'flash_admin_error');
}
////////
$errors = 'O EROARE';
$this->set(compact('errors'));
}
else
{
// GET ERRORS to display it nicely :)
$errors = $this->Event->invalidFields();
$flash = '';
foreach($errors as $error)
{
$flash .= $error."<br />";
}
$this->Session->setFlash($flash, 'flash_admin_error');
}
I know that there is a way to get rid of form field errors using 'error' => false, but i want to set this for the entire application, thus for all fields in all forms.
It has to be there a way of setting that fot the object itself, and I would be gratefull if someone would tell me.
Thaks a lot!
Edit: This doesn't really disable error output, but will hide the error: go to webroot/css/cake.generic.css add display:none to selector div.error-message. That's the simplest way to achieve what you want that I can think of.
Though it may seem like a bit of an extreme approach to override a single property, you can achieve this by extend the core FormHelper. This will allow you to make Anh Pham's original suggestion the default for all FormHelper instances:
// app/views/helpers/app_form.php
App::import('Helper', 'Time');
class AppFormHelper extends FormHelper {
public $_inputDefaults = array('error' => false);
}
Now to use this as-is in CakePHP 1.3, you would have to use "AppForm" throughout your application to refer to this helper from now on (ie. $this->AppForm->input()). CakePHP 2.0 introduces helper aliasing to overcome this, but for now one has to resort to a bit of trickery to continue using "Form" instead. One blog post I found shows how to backport the functionality and another manages allow the helper to do it itself. I personally use the following without any problems:
// app/views/app.php
class AppView extends View {
function &_loadHelpers(&$loaded, $helpers, $parent = null) {
$return = parent::_loadHelpers($loaded, $helpers, $parent);
# rename App helpers (ie. AppHtml -> Html)
foreach ($return as $helperName => $helper) {
if (substr($helperName, 0, 3) === 'App') {
$newHelperName = substr($helperName, 3);
$return[$newHelperName] = $return[$helperName];
}
}
# done
return $return;
}
}
To use the new created classes above, just add the following to your AppController:
// app/app_controller.php
class AppController extends Controller {
public $helpers = array(/*...*/, 'AppForm');
public $view = array('App');
}
I have a many to many relation between Product and Properties. I'm using embedRelation() in my Product form to edit a Product and it's Properties. Properties includes images which causes my issue. Every time I save the form the updated_at column is updated for file properties even when no file is uploaded.
Therefore, I want to exclude empty properties when saving my form.
I'm using Symfony 1.4 and Doctrine 1.2.
I'm thinking something like this in my ProductForm.class.php, but I need some input on how to make this work.
Thanks
class ProductForm extends BaseProductForm
{
public function configure()
{
unset($this['created_at'], $this['updated_at'], $this['id'], $this['slug']);
$this->embedRelation('ProductProperties');
}
public function saveEmbeddedForms($con = null, $forms = null)
{
if (null === $forms)
{
$properties = $this->getValue('ProductProperties');
$forms = $this->embeddedForms;
foreach($properties as $p)
{
// If property value is empty, unset from $forms['ProductProperties']
}
}
}
}
I ended up avoiding Symfony's forms and saving models instead of saving forms. It can be easier when playing with embedded forms. http://arialdomartini.wordpress.com/2011/04/01/how-to-kill-symfony%E2%80%99s-forms-and-live-well/
Solved it by checking if posted value is a file, and if both filename and value_delete is null I unset from the array. It might not be best practice, but it works for now.
Solution based on http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms
class ProductPropertyValidatorSchema extends sfValidatorSchema
{
protected function configure($options = array(), $messages = array())
{
// N0thing to configure
}
protected function doClean($values)
{
$errorSchema = new sfValidatorErrorSchema($this);
foreach($values as $key => $value)
{
$errorSchemaLocal = new sfValidatorErrorSchema($this);
if(array_key_exists('value_delete', $values))
{
if(!$value && !$values['value_delete'])
{
unset($values[$key]);
}
}
// Some error for this embedded-form
if (count($errorSchemaLocal))
{
$errorSchema->addError($errorSchemaLocal, (string) $key);
}
}
// Throws the error for the main form
if (count($errorSchema))
{
throw new sfValidatorErrorSchema($this, $errorSchema);
}
return $values;
}
}
i have an app which has btn to preview report made in crystal report. I added Dataset as datasource of the report and dragged datatable from the toolbox and added the fields I need as columns. I got the instruction from this link http://aspalliance.com/2049_Use_LINQ_to_Retrieve_Data_for_Your_Crystal_Reports.2. This is my 2nd report the first one works and did not encounter any prob at all that is why i am confused, not to mention it also has nullable column. the error says: DataSet does not support System.Nullable<>.
private void ShowReportView()
{
string reportFile = "JudgeInfoFMReport.rpt";
ObservableCollection<tblJudgeFileMaint> judgeFileMaintList;
judgeFileMaintList = GenerateReport();
if (judgeFileMaintList.Count > 0)
{
CrystalReportViewerUC crview2 = new CrystalReportViewerUC();
crview2.SetReportPathFile(reportFile, judgeFileMaintList);
crview2.ShowDialog();
}
else
{
System.Windows.MessageBox.Show("No record found.", module, MessageBoxButton.OK, MessageBoxImage.Information);
}
}
private ObservableCollection<tblJudgeFileMaint> GenerateReport()
{
var result = FileMaintenanceBusiness.Instance.GetAllJudgeInfoList();
return new ObservableCollection<tblJudgeFileMaint>(result);
}
The error is in the part where I set datasource report.SetDataSource
public bool SetReportPathFile(string reportPathFile, IEnumerable enumerable)
{
string reportFolder = #"\CrystalReportViewer\Reports\";
string filename = System.Windows.Forms.Application.StartupPath + reportFolder + reportPathFile; // "\\Reports\\CrystalReports\\DateWiseEmployeeInfoReport.rpt";
ReportPathFile = filename;
report.Load(ReportPathFile);
report.SetDataSource(enumerable);
report.SetDatabaseLogon("sa", "admin007");
bRet = true;
}
_IsLoaded = bRet;
return bRet;
}
I read some answers and says I should set the null value to DBNUll which I did in the properties window of each column if it is nullable. Can anyone help me please? thanks
Your question can be seen in this post, but in a generic way ... that way you can pass an Object to a DataSet typed!
.NET - Convert Generic Collection to DataTable
figured it out. by using a collectionextention, copied somewhere, I forgot the link. Os to whoever it is who made the class, credits to you.
class method looks like this.
public statis class CollectionExtension {
public static DataSet ToDataSet<T>(this IEnumerable<T> collection, string dataTableName)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
if (string.IsNullOrEmpty(dataTableName))
{
throw new ArgumentNullException("dataTableName");
}
DataSet data = new DataSet("NewDataSet");
data.Tables.Add(FillDataTable(dataTableName, collection));
return data;
}
}
then you can use it by doing this in getting your source to your report:
private DataSet GenerateNeutralContEducReport(string dsName)
{
var contEduHistoryList = FileMaintenanceBusiness.Instance.GetManyNeutralFMContEducHistoryInfobyKeyword(CurrentNeutralFM.NeutralID, "NeutralID").ToList();
return CollectionExtensions.ToDataSet<tblContinuingEducationHistory>(contEduHistoryList, dsName);
}
I found little help from the other proposed answers but this solution worked.
A different way to solve this problem is to make the data column nullable.
DataColumn column = new DataColumn("column", Type.GetType("System.Int32"));
column.AllowDBNull = true;
dataTable.Columns.Add(column);
https://learn.microsoft.com/en-us/dotnet/api/system.data.datacolumn.allowdbnull?view=netcore-3.1
foreach (PropertyDescriptor property in properties)
{
dt.Columns.Add(property.Name, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
}
So how does one obtain the previous value of a custom field in a Jira IssueEventListener? I am writing a custom handler for the issueUpdated(IssueEvent) event and I would like to alter the handler's behavior if a certain custom field has changed. To detect the type of change I would like to compare the previous and current values.
(I'm am not asking about how to obtain its current value - I know how to get that from the related Issue)
I am developing against Jira 4.0.2 on Windows.
Is the best way to scan the change history for the last known value?
List changes = changeHistoryManager.getChangeHistoriesForUser(issue, user);
I'm assuming the original poster is writing a JIRA plugin with Java. I cannot be certain of how to accomplish this task in JIRA v4.0.2, but here is how I managed to do so with JIRA v5.0.2 (the solutions may very well be the same):
public void workflowEvent( IssueEvent event )
{
Long eventTypeId = event.getEventTypeId();
if( eventTypeId.equals( EventType.ISSUE_UPDATED_ID ) )
{
List<GenericValue> changeItemList = null;
try
{
changeItemList = event.getChangeLog().getRelated( "ChildChangeItem" );
}
catch( GenericEntityException e )
{
// Error or do what you need to do here.
e.printStackTrace();
}
if( changeItemList == null )
{
// Same deal here.
return;
}
Iterator<GenericValue> changeItemListIterator = changeItemList.iterator();
while( changeItemListIterator.hasNext() )
{
GenericValue changeItem = ( GenericValue )changeItemListIterator.next();
String fieldName = changeItem.get( "field" ).toString();
if( fieldName.equals( customFieldName ) ) // Name of custom field.
{
Object oldValue = changeItem.get( "oldvalue" );
Object newValue = changeItem.get( "newvalue" );
}
}
}
}
Some possible key values for changeItem are:
newvalue
oldstring
field
id
fieldtype
newstring
oldvalue
group
For many of the custom field types Object oldValue is probably just a String. But I don't think that's true for every case.
Try this example :
String codeProjetOldValue= "";
List<GenericValue> changeItemList = issueEvent.getChangeLog().getRelated("ChildChangeItem");
for (GenericValue genericValue : changeItemList) {
if(champCodeProjet.equals(genericValue.get("field"))){
codeProjetOldValue=genericValue.getString("oldstring");
break;
}
}
Note that : champCodeProjet is the name of customfield.