save() not working in ext4yii ExtFormController - extjs

i tried to insert data using ext4yii form. But the save function in not working. plz look through my code
code of formpanel
<ext:Window ClassName="WelcomeWindow" width="500" iconCls="IconApplication"
bodyPadding="25" bodyStyle="background-color:#fff" layout="fit"
title="<?php echo Yii::app()->name;?>" closable="false"
maximizable="false">
<prop:Items>
<ext:FormPanel itemId="form1" width="300" title="myform" autoScroll="true">
<prop:Form>
<ext:CRUDForm controller="ContactForm" />
</prop:Form>
<prop:DockedItems>
<?php
include 'ContactView_Editor_Toolbar.php';
?>
</prop:DockedItems>
<prop:Items>
<ext:TextField name="Name" fieldLabel="Name"/>
<ext:TextField name="address" fieldLabel="Address"/>
</prop:Items>
<prop:InstanceBody>
<script>
(function(){
return {
StartSaveContact:function()
{
var me = this;
me.mode='new_contact';
var msg = me.mode == 'new_contact' ? 'New contact created successfully.' : 'Contact saved successfully.';
var form = me.getForm();
if(form.isValid()) {
var lm = Ext4Yii.newLoadMask(me,'Please wait...',true);
form.submit({
params:{
mode:me.mode
},
success:function(form,response) {
lm.hide();
Ext.MessageBox.show({
title: me.title,
msg: msg,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO,
fn:function() {
}
});
},
failure:function(form,response) {
lm.hide();
Ext.MessageBox.show({
title: me.title,
msg: response.result.message,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR,
fn:function() {
}
});
}
});
}
}
}
})()
</script>
</prop:InstanceBody>
</ext:FormPanel>
</prop:Items>
</ext:Window>
code of contactformcontroller
class ContactFormController extends ExtFormController
{
public function load($request) {
}
public function save($data)
{
$customer = new Employee();
/**
* We can use the setAttributes method on the Customer model
* since the form names have the same name as the attributes.
*/
$customer->setAttributes($data);
if( $customer->save())
$this->exportData($customer);
else
$this->exportException("Don't know what to do..");
}
}
the failure function is trigering without showing any message.
Thanks for advance

If you look with firebug , then what kind of error do you get?

Related

In a Salesforce LWC app how can I add checkbox values to an object's field and show it in a data-table?

I have made my research, but couldn't find the answer.
I have a Lightning App in Salesforce, I used LWC Js and Apex.
In one part of the app the user can add a 'desk item' (by typing its name) and select from a checkbox 1-2 items to add them to the 'desk'.
I used Apex to transfer the value of the 'desk item' to an Object and I can show it in a list (in the app).
How can I add the checkbox value(s) to the submitDesk(){...} so it sends its value(s) along with the 'desk item' value?
I don' know where/how exactly to add and to get it back?
The JS Code
import { LightningElement, track } from 'lwc';
import createDesk from '#salesforce/apex/FlexOfficeController.createDesk';
import getDesks from '#salesforce/apex/FlexOfficeController.getDesks';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class DeskList extends LightningElement {
// Desk
#track data_desks = [];
//table to show the desks's Id + Name, and the checkbox
columns = [
{ label: 'Id', fieldName: 'Id', type: 'text' },
{ label: 'Name', fieldName: 'Name', type: 'text' },
{ label: 'Accessories', fieldName: **the checkbox value**, type: 'text' }
];
// value to the picklist
connectedCallback(){
this.retreiveDesk();
}
retreiveDesk(){
getDesks({})
.then(d => {
this.data_desks = JSON.parse(d);
})
}
desk = {};
changeValue(event){
this.desk[event.target.name] = event.target.value
}
submitDesk(){
console.log(this.desk, this.value + 'Hi there');
createDesk({desk:JSON.stringify(this.desk)})
.then(data=> {
console.log(data + 'hello');
this.retreiveDesk();
// toaster
const evt = new ShowToastEvent({
title: "New desk",
message: `succefully created. Check out your reservation.`,
variant: "success"
})
this.dispatchEvent(evt);
})
}
// Checkbox
value = [];
get options() {
return [
{ label: 'Mouse', value: 'mouse' },
{ label: 'Screen', value: 'screen' },
];
}
// put the checkbox values into a string ('join')
get checkboxValues() {
console.log(this.value);
return this.value.join(',');
}
handleCheckboxChange(event) {
this.value = event.detail.value;
}
}
Apex Controller
public class FlexOfficeController {
#AuraEnabled
public static string createDesk(String desk){
try {
Desk__c d = (Desk__c)JSON.deserialize(desk, Desk__c.class);
insert d;
return d.id;
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
}
#AuraEnabled
public static string getDesks(){
try {
List<Desk__c> desks = new List<Desk__c> ();
desks = [SELECT Id, Name FROM Desk__c];
return JSON.serialize(desks);
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
}
}
HTML
<template>
<lightning-card>
<div class="slds-m-around_medium slds-theme_alert-texture">
<lightning-input name="Name" label="Name your desk" onchange={changeValue}></lightning-input>
<lightning-checkbox-group name="Accessories" label="Checkbox Group" options={options} value={value}
onchange={handleCheckboxChange}></lightning-checkbox-group>
<p>{checkboxValues}</p>
<lightning-button onclick={submitDesk} label="Submit"></lightning-button>
<lightning-datatable key-field="id" data={data_desks} columns={columns} hide-checkbox-column></lightning-datatable>
</div>
</lightning-card>
</template>

Refresh Datatable in for:each loop: Lightning Web Components

I am having trouble refreshing a Datatable in my Lightning Web Component after updating a record. I am calling an onclick action on a button within the row, and imperatively calling an Apex method to update that record. I then call the refreshApex() to update the data being fed into the Datatable.
However, after the refreshApex(), the tables within the for:each are not being refreshed with new data.
The records are properly modified and reflect the changes properly when refreshing the entire page.
Note: The Task object is not supported in LWC, and I cannot use the updateRecord() method to update these records.
HTML:
<template>
<template if:true="{taskCompWrapperList}">
<!--<lightning-layout multiple-rows="false" pull-to-boundary="small">-->
<template for:each="{taskCompWrapperList}" for:item="taskTemplate">
<lightning-layout-item
key="{taskTemplate.taskSectionOrder}"
size="3"
class="slds-p-around_x-small"
>
<!-- Start bear tile -->
<lightning-card title="{taskTemplate.taskSectionTitle}">
<div class="slds-m-around_medium">
<template if:true="{taskTemplate.taskList}">
<lightning-datatable
key-field="Id"
data="{taskTemplate.taskList}"
onrowaction="{handleRowAction}"
columns="{columns}"
onsave="{handleSave}"
draft-values="{draftValues}"
>
</lightning-datatable>
</template>
<template if:true="{contact.error}">
<!-- handle Apex error -->
</template>
</div>
</lightning-card>
<!-- End bear tile -->
</lightning-layout-item>
</template>
<!--</lightning-layout>-->
</template>
</template>
Javascript:
import { LightningElement, api, wire ,track} from 'lwc';
import getTaskCompWrappers from '#salesforce/apex/ENT_Task_Utility.getTaskComponentWrapper';
import updateTask from '#salesforce/apex/ENT_Task_Utility.updateTask';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { updateRecord } from 'lightning/uiRecordApi';
import { refreshApex } from '#salesforce/apex';
const COLS = [
{
type: 'button',
label: 'Complete',
typeAttributes:
{
//iconName: 'action:preview',
label: 'Complete',
name: 'Complete',
title: 'Complete',
value: 'Complete',
variant: 'brand',
alternativeText: 'Complete'
}
},
{
type: 'button-icon',
label: 'Start',
typeAttributes:
{
iconName: 'action:approval',
//label: 'Complete',
name: 'Start',
title: 'Start',
value: 'Start',
variant: 'success',
alternativeText: 'Start',
}
},
{
type: "button",
typeAttributes:
{
label: 'View',
name: 'View',
title: 'View',
disabled: false,
value: 'view',
iconPosition: 'left'
}
},
{
type: "button",
typeAttributes:
{
label: 'Edit',
name: 'Edit',
title: 'Edit',
disabled: false,
value: 'edit',
iconPosition: 'left'
}
},
//{ label: 'Complete', fieldName: 'Task_Complete__c', editable: true },
{ label: 'Status', fieldName: 'Status', type: 'picklist', editable: true },
{ label: 'Completed', fieldName: 'Completed', type: 'boolean', editable: true },
{ label: 'Owner', fieldName: 'OwnerId', editable: true },
{ label: 'Subject', fieldName: 'Subject' },
{ label: 'Due Date', fieldName: 'ActivityDate', type: 'date' }
];
export default class ENT_Task_Utility_LWC extends LightningElement {
#api objApiName;
#api recordId;
#track testMessage = 'Test Failed :c';
#track error;
#track columns = COLS;
#track draftValues = [];
taskCompWrapperList;
#track error;
//#wire(getTasks, {recordId: '$recordId'}) taskList;`
#wire(getTaskCompWrappers, {recordId: '$recordId', objApiName: '$objApiName'})
taskCompWrapperListWire({ error, data }) {
if (data) {
this.taskCompWrapperList = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.taskCompWrapperList = undefined;
}
}
updateTaskValues (taskId, taskStatus) {
// eslint-disable-next-line no-console
console.log('updateTaskValues hit');
for(var counter = 0; counter < this.taskCompWrapperList.length; counter++) {
// eslint-disable-next-line no-console
console.log('taskWrapper: ' + this.taskCompWrapperList[counter]);
for(var counter2 = 0; counter2 < this.taskCompWrapperList[counter].taskList.length; counter2++) {
// eslint-disable-next-line no-console
console.log('task: ' + this.taskCompWrapperList[counter].taskList[counter2]);
if(this.taskCompWrapperList[counter].taskList[counter2].Id == taskId)
{
this.dispatchEvent(
new ShowToastEvent({
title: 'Task Id Found!',
message: this.taskCompWrapperList[counter].taskList[counter2].Id,
variant: 'success'
})
);
this.taskCompWrapperList[counter].taskList[counter2].Status = taskStatus;
}
}
}
}
handleRowAction(event) {
//TODO
}
}
Apex methods:
#AuraEnabled(cacheable=true)
global static List<Task> getTasks(String recordId)
{
return [SELECT Id, Subject, OwnerId FROM Task WHERE WhatId = :recordId];
}
#AuraEnabled(cacheable=true)
global static List<ENT_Task_Comp_Wrapper> getTaskComponentWrapper(String recordId, String objApiName)
{
List<Task_Template__c> taskTemplateList = [SELECT Id, Task_Component_Section_Order__c, Task_Component_Section_Title__c, (SELECT Id FROM Task_Template_Items__r)
FROM Task_Template__c
WHERE Active__c = true AND sObject__c = :objApiName ORDER BY Task_Component_Section_Order__c ASC];
List<Task> taskList = [SELECT Id, Task_Template_Item__c, OwnerId, Owner.Name, Subject, Description, Status, ActivityDate, Task_Complete__c FROM TasK WHERE WhatId = :recordId];
List<ENT_Task_Comp_Wrapper> taskCompWrapperList = new List<ENT_Task_Comp_Wrapper>();
for(Task_Template__c taskTemplate : taskTemplateList)
{
ENT_Task_Comp_Wrapper taskCompWrapper = new ENT_Task_Comp_Wrapper();
taskCompWrapper.taskSectionTitle = taskTemplate.Task_Component_Section_Title__c;
taskCompWrapper.taskSectionOrder = (Integer)taskTemplate.Task_Component_Section_Order__c;
taskCompWrapper.taskList = new List<Task>();
for(Task currentTask : taskList)
{
for(Task_Template_Item__c taskTemplateItem : taskTemplate.Task_Template_Items__r)
{
if(taskTemplateItem.Id == currentTask.Task_Template_Item__c)
{
taskCompWrapper.taskList.add(currentTask);
}
}
}
taskCompWrapperList.add(taskCompWrapper);
}
System.debug(taskCompWrapperList);
return taskCompWrapperList;
}
#AuraEnabled
global static void updateTask(String taskId, String newStatus)
{
System.debug(taskId);
Task taskToUpdate = new Task(Id = taskId, Status = newStatus);
update taskToUpdate;
//update taskToUpdate;
}
#AuraEnabled
global static void updateTask(String taskId, String newStatus)
{
System.debug(taskId);
Task taskToUpdate = new Task(Id = taskId, Status = newStatus);
update taskToUpdate;
//update taskToUpdate;
}
In your JS code you have imported refreshApex
by using this line import { refreshApex } from '#salesforce/apex';
but you didn't assigned to any wire method. Hence data is not refreshed
Please refer this documentation.
To refresh a wired method, pass the argument the wired method receives (which is the wired value) to refreshApex(). In this sample code, the wired method is taskCompWrapperListWire. Hold on to the value provisioned by the wire service and pass it to refreshApex().
#wire(getTaskCompWrappers, {recordId: '$recordId', objApiName: '$objApiName'})
taskCompWrapperListWire({ error, data }) {
if (data) {
this.taskCompWrapperList = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.taskCompWrapperList = undefined;
}
}
And then use refreshApex() as below:
refreshApex(this.taskCompWrapperListWire);
Update you code as below
updateTaskValues({
taskId: this.taskId,
taskStatus: this. taskStatus
})
.then(() => {
// your code logic
refreshApex(this.taskCompWrapperListWire);
})
.catch((error) => {
this.message = 'Error received: code' + error.errorCode + ', ' +
'message ' + error.body.message;
});
you probably need to wait for next release to have a correct way to handle such situation.
You are getting record through uiRecordApi and updating through Apex if I'm correct.
Then you would need to use getRecordNotifyChange() available in Winter 21 release.
Apart from the answer provided by Sudarshan, you should also define taskCompWrapperList as a reactive property to make it rerender when the property is updated.
#track taskCompWrapperList = [];

when i push select2OptionData object in an array, select2 don't display any value

select2 in my angular project. I want to display a select of an array of certificate requested from an api. For each element if I create and push a select2OptionData Object in an array, but when i want to display it in the Html page it is selected but without any option. When i create an array of object like the gitHub demo everything's right.
Can you help me please.
Here is the ts
export class DashboardCvComponent implements OnInit, OnDestroy {
certificateForm: FormGroup;
certificates: Array<Certificate>;
certificatesTypes: Array<Select2OptionData>;
exampleData: Array<Select2OptionData>;
constructor(private formBuilder: FormBuilder, private certificatesService: CertificatesService,
private trainingsService: TrainingsService, private authService: AuthenticationService,
private datepipe: DateFormatPipe, private CvService: CVService, private fileUploaService: FileUploadService) {
this.certificatesTypes = [];
this.exampleData = [];
}
ngOnInit() {
// get certificate types
this.certificatesService.getAllCertificatesType('50').subscribe(
(response) => {
// console.log('-> CERTIFICATES TYPES LOADING successful : ', response);
/* this.certificatesTypes = response.data; */
response.data.forEach(element => {
const certif = {id: element.id.toString(), text: element.name};
this.certificatesTypes.push(certif);
});
this.exampleData = [{
id: 'basic1',
text: 'Basic 1'
},
{
id: 'basic2',
disabled: true,
text: 'Basic 2'
},
{
id: 'basic3',
text: 'Basic 3'
},
{
id: 'basic4',
text: 'Basic 4'
}]
console.log('les certif', this.exampleData, this.certificatesTypes);
},
(error) => {
console.log('-> CERTIFICATES TYPES LOADING failed : ', error);
},
() => {
}
);
and the html
<div class="dashboard--degrees">
<app-certificate *ngFor="let certificate of certificates" [certificate]=certificate [url]=url></app-certificate>
<button class="button button--bluegreen" type="button" data-modal="modal-certificate">
<svg class="icon icon-plus-o">
<use xlink:href="#icon-plus-o"></use>
</svg> <span i18n="##cvcomponent-addcertificate">J'ajoute un diplĂ´me </span>
</button>
<select2 [data]="certificatesTypes"></select2>
<select2 [data]="exampleData"></select2>
</div>
Here the exampleData select display well but not the certificatesTypes
Don't use this.certificate.push inside for loop. it will not work. instead of you can use something like :
let arrCertificates = [];
response.data.forEach(element => {
const certif = {id: element.id.toString(), text: element.name};
arrCertificates.push(certif);
});
this.certificatesTypes = arrCertificates;

Issue with data biding into Picker in Titanium Alloy

I need to display the Picker values from Database. So How can I display the dynamic values in picker.
XML code
<Alloy>
<Collection src="UserLanguage"/>
<Window class="container" onClose="cleanup">
<Picker class="picker">
<PickerColumn dataCollection="UserLanguage" dataTransform="transformFunction">
<PickerRow title="{LanguageName}"/>
</PickerColumn>
</Picker>
<!--<Label id="label"></Label>-->
</Window>
</Alloy>
Model:
var moment = require('alloy/moment');
exports.definition = {
config : {
"columns": {
"id":"text",
"LanguageName":"text"
},
"adapter": {
"type": "sql",
"collection_name": "UserLanguage"
}
},
extendModel: function(Model) {
_.extend(Model.prototype, {
});
return Model;
},
extendCollection: function(Collection) {
_.extend(Collection.prototype, {
});
return Collection;
}
};
Controller
var moment = require('alloy/moment');
var userlang = Alloy.Collections.UserLanguage;
var task = Alloy.createModel('UserLanguage', {
id : '1',
LanguageName : 'English'
});
task.save();
userlang && userlang.fetch();
function transformFunction(model) {
var transform = model.toJSON();
transform.LanguageName = transform.LanguageName ;
return transform;
}
$.index.open();
function cleanup() {
$.destroy();
}
tss:
".container": {
backgroundColor:"black"
},
".picker": {
width: '90%',
top: '25dp'
}
Alloy.js
Alloy.Collections.UserLanguage = Alloy.createCollection('UserLanguage');
How can I pass the selected values in to Picker. The data is not binding in to the XML file, I'm getting the following error,
Uncaught TypeError: cannot read property '_transform' of undefined
index.xml
<Alloy>
<Collection src="UserLanguage"/>
<Window>
<Picker id="countryPicker" class="picker">
<PickerColumn id="column1" dataCollection="UserLanguage">
<PickerRow title="{LanguageName}"/>
</PickerColumn>
</Picker>
</Window>
</Alloy>
index.js
Alloy.Collections.UserLanguage.fetch();
$.index.open();
Don't forget to call $.destroy after window is closed. See http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Data_Binding
Another solution:
index.xml
<Alloy>
<Collection src="UserLanguage"/>
<Window>
<Picker id="picker"/>
</Window>
</Alloy>
index.js
var userLanguage = Alloy.Collections.UserLanguage;
userLanguage.on("reset", function() {
var column = Ti.UI.createPickerColumn();
this.each(function(model) {
var row = Ti.UI.createPickerRow({
title: model.get("LanguageName");
});
column.addRow(row);
});
$.picker.columns = [column];
});
userLanguage.fetch();
$.index.open();

netzke FormPanel

I think i stucked here. I have a model (Test) with 3 fields: id, name, name2. So i want to write there something and click on Apply button on bottom and if all fields are filled and passed validation (i guess this i should do in model Test.rb, yeah?) and get to localhost:3000/some/where and if i left some filed (name or name2) unfilled so i get a message like "ERROR".
test_panel.rb
class TestPanel < Netzke::Basepack::FormPanel
js_mixin :actions
def configuration
super.merge(
:name => :test_panel,
:model => 'Test',
:title => "TEST PANEL",
)
end
end
action.js
{
onApply: function() {
var form = this.getForm();
if (form.isValid()) {
this.Apply(form.getFieldValues(), function(success) {
if (success) {
window.location = 'some/where';
} else {
Ext.Msg.show({
title: 'FF',
msg: 'I guess you have an error!!',
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING });
}
}, this);
} else {
Ext.Msg.show({
title: 'FF',
msg: 'Fill all fields!!',
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING });
}
}
}
If my understanding is correct no need to do any thing with netzke. Just write your validators in the rails model. If any field is failed to pass the validation Netzke will capture the validation message from rails model and display it on top of the grid.

Resources