Update two models using yii x-editable - php

So, I'm using this extension: x-editable for yii.
And I'm currently trying to update two models in update() function.
I have two models:
Realisasi.php
RealisasiDeadline.php.
So when a cell is updated on table Realisasi.php (one value in column t1701 in this case), I want the function to update the corresponding value in column t1701 of table RealisasiDeadline, using column no as the foreign key.
Since I haven't found any example on Google, I made it up myself:
public function actionSimpanEdit($kode) {
Yii::import('editable.EditableSaver');
$es = new EditableSaver($_GET['model']); // 'modelName' is classname of model to be updated
$es->update();
$es2 = RealisasiDeadline::model()->findByPk($kode);//this is where I'm stuck
$es2['t1701'] = '1991-11-19';//this too
$es->update();//and this
}
This is the view.php:
array(
'name' => 't1701',
'value' => 'CHtml::value($data,"hubtarget.t1701")=== "0"?"Target Nol":$data->t1701',
'header' => 'Bkl Selatan',
'class' => 'editable.EditableColumn',
'editable' => array(
'url' => $this->createUrl('simpanEdit', array('model' => 'Realisasi', 'kode'=>'$data->no')),
)
),
What have I missed? Is it possible at all to do? If not, is there another solution?
UPDATE
It's not showing any error. But the value in table RealisasiDeadline doesn't change, only the one in Realisasi does.

Added some comments to original function so you can improve upon it. Biggest issue with this code is that looking at it I have no idea what it does.
public function actionSimpanEdit($kode) {
Yii::import('editable.EditableSaver'); // Should be at the top of the file
// For the love of god use descriptive variable names
$es = new EditableSaver($_GET['model']); // Would prefer to have model as actions argument
$es->update();
$es2 = RealisasiDeadline::model()->findByPk($kode); // no idea what this model is responsible for
$es2['t1701'] = '1991-11-19'; // no idea what attribute t1701 is, use descriptive names
$es->update();
}
I have refactored it a bit. Still have no idea what it does ;/
public function actionSimpanEdit($id, $model) {
$editableSaver = new EditableSaver($model);
$editableSaver->update();
$deadline = RealisasiDeadline::model()->findByPk($id);
if($deadline instanceof RealisasiDeadline) {
$deadline->t1701 = '1991-11-19';
if(!$deadline->update()) {
// something went wrong
}
} else {
// not found
}
}
Going back to your problem. It is probably caused by RealisasiDeadline model being not found or some behavior or event preventing it from update.

Related

How to automatically fill other form fields after one field is filled?

I'm creating a form in moodle using moodleform class. I have many fields in the form. What I'm wanting to do is when the user fills in the first field, I want to get the data that he/she entered, search the relevant DB table for a field that matches that input, then populate the other fields for that record.
Please note that the user hasn't pressed any submit button yet. I've been trying to find a function that gets the entered data but all efforts have been in vain. What I found was a get_data() method but I don't even know how to use that correctly. I've been reading the moodle docs but nothing is helping. I'm not a beginner to coding but neither am I an expert.
Here's a code snippet:
class requestcourse_form extends moodleform
{
function definition()
{
global $CFG, $currentsess, $DB, $USER, $currentrecord;
$mform =& $this->_form; // Don't forget the underscore!
// Form header
$mform->addElement('header', 'mainheader','<span style="font-size:22px">'.get_string('courserequestform','block_usp_mcrs'). '</span>');
// Course Code field.
$coursecodearray = array();
$coursecodearray[0] = get_string('choosecoursecode', 'block_usp_mcrs');
$allcoursecodes = $DB->get_records_select('block_usp_mcrs_courses', 'id > 0', array(), 'id', 'id, course_code');
foreach ($allcoursecodes as $id => $coursecodeobject) {
$coursecodearray[$id] = $coursecodeobject->course_code;
}
$coursecode = $mform->addElement('select', 'coursecode', get_string('coursecode', 'block_usp_mcrs'), $coursecodearray);
$mform->addRule('coursecode', get_string('required'), 'required', null, 'client');
$mform->setType('coursecode', PARAM_RAW);
// Course Name field. TODO: Course Name to pick automatically after entering Course Code
$coursenamearray = array();
$coursenamearray[0] = get_string('choosecoursename', 'block_usp_mcrs');
$allcoursenames = $DB->get_records_select('block_usp_mcrs_courses', 'id > 0', array(), 'id', 'id, course_name');
foreach ($allcoursenames as $id => $coursenameobject) {
$coursenamearray[$id] = $coursenameobject->course_name;
}
$mform->addElement('select', 'coursename', get_string('coursename', 'block_usp_mcrs'), $coursenamearray);
$mform->addRule('coursename', get_string('required'), 'required', null, 'client');
$mform->setType('coursename', PARAM_RAW);
Any help would be appreciated.
You have to achieve this using javascript, as Moodle has no functionality to fill data in a nested way.
Add AMD module js file where you are calling your mform for display purpose.
In the file where you render your mform
$mform->render();
add below line to call you amd js file.
$PAGE->requires->js_call_amd('local_acestructure/registration', 'init');
In your amd js file make httprequest / ajax call to fetch data based on your course_code select drop down change.
Thank you.

How to properly display a calculated value of a non-db field in the ListView?

In Suitecrm/SugarCRM 6.5
I need to modify the ListView. Showing the value of a field based on a certain condition.
In the Account module, the name field may be empty based on certain conditions, I require that when this occurs show the value of a custom field. To do this, first I tryied using 'customCode' + smarty as usual in Edit/Detail vies, but in several posts mention that this is not possible in the ListView. The concession is to use logic hooks + a non-db field to store the calculated field. Following this SO answer I have written the following:
Custom field at custom/Extension/modules/Accounts/Ext/Vardefs/custom_field_name_c.php
<?php
$dictionary['Account']['fields']['name_c']['name'] = 'account_name_c';
$dictionary['Account']['fields']['name_c']['vname'] = 'LBL_ACCOUNT_NAME_C';
$dictionary['Account']['fields']['name_c']['type'] = 'varchar';
$dictionary['Account']['fields']['name_c']['len'] = '255';
$dictionary['Account']['fields']['name_c']['source'] = 'non-db';
$dictionary['Account']['fields']['name_c']['dbType'] = 'non-db';
$dictionary['Account']['fields']['name_c']['studio'] = 'visible';
Label at suitecrm/custom/Extension/modules/Accounts/Ext/Language/es_ES.account_name_c.php
<?php
$mod_strings['LBL_ACCOUNT_NAME_C'] = 'Nombre de cuenta';
Logic hook entry at custom/modules/Accounts/logic_hooks.php
$hook_array['process_record'] = Array();
$hook_array['process_record'][] = Array(
2,
'Get proper name',
'custom/modules/Accounts/hooks/ListViewLogicHook.php',
'ListViewLogicHook',
'getProperName'
);
Logic hook at custom/modules/Accounts/hooks/ListViewLogicHook.php
<?php
class ListViewLogicHook
{
public function getProperName(&$bean, $event, $arguments)
{
if (empty($bean->fetched_row['name'])) {
$bean->account_name_c = $bean->fetched_row['person_name_c'];
} else {
$bean->account_name_c = $bean->fetched_row['name'];
}
// Here I also tried, but same result
// $bean->account_name_c = empty($bean->name) ? $bean->person_name_c : $bean->name;
}
}
listviewdefs.php at custom/modules/Accounts/metadata/listviewdefs.php
I added the field
'NAME_C' =>
array (
'width' => '20%',
'label' => 'LBL_ACCOUNT_NAME_C',
'default' => true,
),
After these modifications and repair I hope to see the field full with the right value. But it appears empty. I have verified that the logic hook is properly called, but the name andperson_name_c fields are always empty. In case it is relevant I have verified in Studio that the name fields in Account is typename I do not know what this means when it comes to obtaining its value.
I appreciate your comments
The problem is in the logic hook is due to first that the $bean does not have access to the custom fields, so I have to invoke them using $bean->custom_fields->retrieve(); Also the name field is always empty, I had to use DBManager to get only the name field.
The logic of the final logic hook is the following:
<?php
class ListViewLogicHook
{
public function getProperName($bean, $event, $arguments)
{
// Get access to custom fields from $bean
$bean->custom_fields->retrieve();
// Get access to name property using DBManager because $bean->name return null
$sql = "SELECT name FROM accounts WHERE id = '{$bean->id}'";
$name = $GLOBALS['db']->getOne($sql);
// Assign a value to non-db field
$bean->name_c = empty($name) ? $bean->nombre_persona_c : $name;
}
}
I was not familiar with the method $bean->custom_fields->retrieve() and at the moment I do not know why is empty the name field and I understand others fields remain empty.
I hope this is useful
We achieved that doing an after_retrieve hook, very fast and simple - This is taken from a working example.
public function RemoveCost(&$bean, $event, $arguments)
{
global $current_user;
include_once(‘modules/ACLRoles/ACLRole.php’);
$roles = ACLRole::getUserRoleNames($current_user->id);
if(!array_search("CanSeeCostRoleName",$roles)){
$bean->cost = 0;
$bean->cost_usdollar = 0;
}
}
All you need is to define and add this function to the module logic_hooks.php
You can even tailor down to specific calls:
if (isset($_REQUEST['module'],$_REQUEST['action']) && $_REQUEST['module'] == 'Opportunities' && $_REQUEST['action'] == 'DetailView')
As some times there are views you do want to show the field, for example quicksearch popup.

What does isDirty() mean in Laravel?

First of all, I am not familiar with Laravel so much (or with the term "dirty" for that matter).
I stumbled upon this line of code -
if ($this->isDirty('status')) {
if (Notification::has('website-status-' . strtolower($this->status))) {
Notification::set($this->account, 'website-status-' . strtolower($this->status), $this->emailAttributes())
->email();
}
}
And I couldn't understand what that means exactly. I tried to find out on the internet but the Laravel site only says this
"Determine if a given attribute is dirty"
which doesn't really help...
When you want to know if the model has been edited since it was queried from the database, or isn't saved at all, then you use the ->isDirty() function.
The isDirty method determines if any attributes have been changed since the model was loaded. You may pass a specific attribute name to determine if a particular attribute is dirty.
$user = User::create([
'first_name' => 'Amir',
'last_name' => 'Kaftari',
'title' => 'Developer',
]);
$user->title = 'Jafar';
$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false
Eloquent provides the isDirty, isClean, and wasChanged methods to examine the internal state of your model and determine how its attributes have changed from when they were originally loaded.
You can find complete description and examples of these three methods here in the official document:
https://laravel.com/docs/9.x/eloquent#examining-attribute-changes
As support for the accepted answer:
$model = Model::find(1);
$model->first_column = $request->first_value;
$model->second_column = $request->second_value;
$model->third_column = $request->third_value;
if($model->isDirty()){
// the model has been edited, else codes here will not be executed
}
$model->save();

Pushing data to Dojo Filteringselect (with code)

I'm quite new to Zend & JSON, however I have the need to learn. What I want to achieve is: having a Dojo filteringselect (with autocomplete) control which is linked to zipcodes from a database (and which keeps track of the ID, so I can store that ID as a FK in another table (later on). The structure is MVC. I do get results from the database, however I can't seem to make it shine. Nothing shows up in the filteringselect control. So basicly the structure field of my database needs to get into the filteringsselect control and keeping track of that id, because I need it later on as a FK in another table.
Please help me out!
Table:
<?php
class Application_Model_Place extends FS_Model_Popo {
protected $_fields = array(
'id' => NULL,
'zip' => NULL,
'name' => NULL,
'up' => NULL,
'structure' => NULL);
protected $_primaryKey = array('id');
}
Form:
$place = new Zend_Dojo_Form_Element_FilteringSelect('Place');
$place->setLabel('Place')
->setAttrib('title', 'Add a place.')
->setAutoComplete(true)
->setStoreId('placeStore')
->setStoreType('dojox.data.QueryReadStore')
->setStoreParams(array('url' => '/graph/place/autocomplete'))
->setAttrib("searchAttr", "structure")
->setRequired(true);
Controller:
class Graph_PlaceController extends Zend_Controller_Action {
public function autocompleteAction() {
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
$structuur = $this->_getParam("structure", "");
$results = FS_Model_Factory::getInstance()->place->autocomplete(array('structure like ?'=> "%".$structure."%"));
$enc_res = array();
foreach ($results as $value) {
array_push($enc_res,$this->_helper->convert->toArray($value));
}
$this->_helper->json($enc_res);
$data = new Zend_Dojo_Data('id', $enc_res);
$this->_helper->autoCompleteDojo($data);
}
}
An example of json($enc_res) would be:
{"id":"235","zip":"3130","name":"Betekom","up":"BETEKOM","structure":"3130 Betekom"}, {"id":"268","zip":"3211","name":"Binkom","up":"BINKOM","structure":"3211 Binkom"},{"id":"377","zip":"3840","name":"Broekom","up":"BROEKOM","structure":"3840 Broekom"},{"id":"393","zip":"1081","name":"Brussel (Koekelberg)","up":"BRUSSEL (KOEKELBERG)","structure":"1081 BRUSSEL (KOEKELBERG)"},{"id":"421","zip":"1081","name":"Bruxelles (Koekelberg)","up":"BRUXELLES (KOEKELBERG)","structure":"1081 BRUXELLES (KOEKELBERG)"},{"id":"668","zip":"3670","name":"Ellikom","up":"ELLIKOM","structure":"3670 Ellikom"},{"id":"1236","zip":"3840","name":"Jesseren (Kolmont)","up":"JESSEREN (KOLMONT)","structure":"3840 Jesseren (Kolmont)"},{"id":"1275","zip":"3370","name":"Kerkom","up":"KERKOM","structure":"3370 Kerkom"}
I think you have several options :
Either you have control on the structure of the json you produce on your controller, and therefore you should generate the format expected by dojox.store.QueryReadStore (which is by default the same as dojo.data.ItemFileReadStore). See http://dojotoolkit.org/reference-guide/dojo/data/ItemFileReadStore.html#general-structure
Or you create a custom store that understands the structure of your json response. See http://dojotoolkit.org/reference-guide/dojox/data/QueryReadStore.html#query-translation
Or you are using dojo >1.6, and you can use dojo.store.JsonRest with its companion dojo.data.ObjectStore as described here
Option 1 is obviously the easiest...

CakePHP: Access Model in other Model / in app_model.php for Validation of Banknumber

I am wondering how I could use data from a Model B while I am validating Model A, here to check if an entered Banknumber is a correct one:
My Users specify their bankaccount during the registration. E.g. the "banknumber". I am validating this the normal way in my user.php model
var $validate = array(
'banknumber' => array(
'minLength' => array(
'rule' => array('minLength', 8),
'message' => '...',
'required' => true,
),
Now I want to know if the entered Banknumber is a real one, so I got a table "Banks" in my DB with all real Banknumbers, and I am using some own validation functions which I specify in app_model.php.
function checkBankExists($data) {
if (!$this->Bank->findByBanknumber($data)) {
return false;
} else {
return true;
}
}
But this is never working, because while I am validating the User-Model, I can only use this one in an app_model - function, accessing it with $this->name or so... a $this->Bank is NOT possible, I get:
Undefined property: User::$Bank [APP\app_model.php
Call to a member function findByBanknumber() on a non-object
Is there ANY way to import/access other models in a function in app_model.php?
Thank you!
ClassRegistry should generally be used instead of AppImport as AppImport only loads the file, rather than registering it properly, cake style.
Using the example above.
$bnk = ClassRegistry::init('Bank');
$bnk->findByBanknumber($data);
you can import your model, create instance of it and use it as you like:
App::import('model','Bank');
$bnk = new Bank();
$bnk->findByBanknumber($data);

Categories