We want to update / edit the Data of a Customer. So we've tried out the original Code from the examples. The example works fine, but we usually have to check the Userinputs before we write that to the Database. Here's my Code:
/**
* Event handler (attached declaratively) for the view save button. Saves the changes added by the user.
* #function
* #public
*/
onSave: function() {
var that = this,
oModel = this.getModel();
// abort if the model has not been changed
if (!oModel.hasPendingChanges()) {
MessageBox.information(
this._oResourceBundle.getText("keine Ă„nderungen"), {
id: "noChangesInfoMessageBox",
styleClass: that.getOwnerComponent().getContentDensityClass()
}
);
return;
}
this.getModel("appView").setProperty("/busy", true);
if (this._oViewModel.getProperty("/mode") === "edit") {
// attach to the request completed event of the batch
oModel.attachEventOnce("batchRequestCompleted", function(oEvent) {
var oParams = oEvent.getParameters();
if (oParams.success) {
that._fnUpdateSuccess();
} else {
that._fnEntityCreationFailed();
}
});
}
oModel.submitChanges();
},
How may I access to the REQUEST Data ? I've tried to look at the oModel DOM, but only found aBindings where a lot of unuseful Stuff is there. Even window.location.search wasn't the solution.
We've fixed it.
Just use this._getFormFields(this.byId("newEntitySimpleForm"));
Related
I use 2 XML fragment, one for display data, the other for edit.
I switch the fragment using this method:
onAfterRendering : function () {
this._toggleForm("Display");
},
_toggleForm : function(sFragmentName) {
var oPage = this._detailPage;
//my detail page has an object header, a fragment form and a form in detail view.
if(oPage.getContent().length > 2) {
oPage.removeContent(1);
}
oPage.insertContent(this._getFormFragment(sFragmentName), 1);
},
_formFragments: {},
_getFormFragment: function (sFragmentName) {
var oFormFragment = this._formFragments[sFragmentName],
oView = this.getView();
if (oFormFragment) {
return oFormFragment;
}
oFormFragment = sap.ui.xmlfragment(oView.getId(), "namespace.fragment." + sFragmentName, this);
oView.addDependent(oFormFragment);
return this._formFragments[sFragmentName] = oFormFragment;
}
Everything works fine... BUT, if I call the app from the Fiori launchpad, the first call is ok, but the second time give me this error in insertContent :
The object with ID XXX-detail--general was destroyed and cannot be used anymore.
Display/Change fragment is destroyed after exit, but this._fromFragment still stored a reference, and returned this reference oFormFragment when _getFormFragment is called when I entered the second time, which caused this error.
Fixed by add:
onExit : function () {
for(var sPropertyName in this._formFragments) {
if(!this._formFragments.hasOwnProperty(sPropertyName)) {
return;
}
this._formFragments[sPropertyName].destroy();
this._formFragments[sPropertyName] = null;
}
}
Answer #AndriiNaumovych 's question:
It seems that only sap.ui.comp.smartform.SmartForm has a EditTogglable property, and it need a sap:updatable="true" in metadata.xml (I saw that in Explore, not specified in doc.)
I use sap.ui.layout.form.SimpleForm, editable seems not working in JSON model without metadata. So I use this example with fragment.
I'm building a app with jquerymobile and I've a page which is a form where I have to fill some info about the field job I have done so I can save it, instead of arriving to the store and fill the paperwork by guessing the time of arrival and the time of the finish.
So, I want to fill the form and when I tap on submit, it saves a txt or another file type on the android phone.
Thanks
This worked for me...
When user clicks the save button
var form_1;
var jsonString;
function saveFormState() {
form_1 = $("#form").find("select,textarea, input").serializeArray();
jsonString = JSON.stringify(form_1);
console.log(jsonString);
getFSToSaveForm();
}
function getFSToSaveForm(){
window.requestFileSystem(LocalFileSystem.PERSISTENT,0 ,function(fileSystem){
var entry=fileSystem.root;
entry.getDirectory('myForms', {create:true, exclusive:false}, function(dirEntry){
dirEntry.getFile('formToSave.json', { create: true, exclusive: false}, saveToJsonFile, onError);
}, onError);
}, onError);
}
function saveToJsonFile(fileEntry){
fileEntry.createWriter(function(writer){
writer.onwrite = function (evt) {
console.log("Wrote to file: " + jsonString);
};
writer.write(jsonString);
}, onError);
}
If you want to restore:
+Read the file and save the read text on a vaiable
Then use some Jquery.
var jsonString;
function getFSToRead(){} //You can find the code in the cordova API http://cordova.apache.org/docs/en/2.5.0/cordova_file_file.md.html
function restoreFormState() {
var newObjectArray ;
newObjectArray = JSON.parse(jsonString);
console.log(newObjectArray.length);
jQuery.each( newObjectArray, function( i, field ) {
$( '#' + field.name).val(field.value);
});
}
Hope that helps
Is there a way to have a form submit create an object in a store under ExtJs 4?
It seems strange to me that the grid is built completely around the store mechanism and I see no obvious way to plug a form into a store. But I am most likely just missing something.
You can add a model instance to a store upon form submit using this code:
onSaveClick: function()
{
var iForm = this.getFormPanel().getForm(),
iValues = iForm.getValues(),
iStore = this.getTasksStore();
iStore.add( iValues );
},
This is within an MVC controller, so this is the controller.
For model editing, you can 'bind' a form to a model instance using loadRecord:
iFormPanel.loadRecord( this.selection );
You can then update the model instance using updateRecord():
iFormPanel.getForm().updateRecord();
Just for fun (and as it might help some), it is similar to the following code:
onSaveClick: function()
{
var iForm = this.getFormPanel().getForm(),
iRecord = iForm.getRecord(),
iValues = iForm.getValues();
iRecord.set ( iValues );
},
If your store is has autoSync: true. An Update (or Create) call will be made via the configured proxy. If there's no autoSync, you'll have to sync your store manually.
You can subclass Ext.form.action.Action to provide load/save actions for a Form to be performed on a Store. The only gotcha is that somehow there's no "official" way to select any non-standard Action in Ext.form.Basic, so I'd suggest an unofficial override:
Ext.define('Ext.form.Advanced', {
override: 'Ext.form.Basic',
submit: function(options) {
var me = this,
action;
options = options || {};
action = options.submitAction || me.submitAction;
if ( action ) {
return me.doAction(action, options);
}
else {
return me.callParent(arguments);
}
},
load: function(options) {
var me = this,
action;
options = options || {};
action = options.loadAction || me.loadAction;
if ( action ) {
return me.doAction(action, options);
}
else {
return me.callParent(arguments);
}
}
});
And, having created the Actions you need, you could then use them in a Form Panel:
Ext.define('My.form.Panel', {
extend: 'Ext.form.Panel',
requires: [ 'Ext.form.Advanced' ],
loadAction: 'My.load.Action',
submitAction: 'My.submit.Action',
...
});
There are other ways and shortcuts though.
I'm building a Metro app using the single-page navigation model. On one of my pages I start an async ajax request that fetches some information. When the request returns I want to insert the received information into the displayed page.
For example:
WinJS.UI.Pages.define("/showstuff.html", {
processed: function (element, options) {
WinJS.xhr(...).done(function (result) {
element.querySelector('#target').innerText = result.responseText;
});
}
};
But how do I know that the user hasn't navigated away from the page in the meantime? It doesn't make sense to try to insert the text on a different page, so how can I make sure that the page that was loading when the request started is still active?
You can compare the pages URI with the current WinJS.Navigation.location to check if you are still on the page. You can use Windows.Foundation.Uri to pull the path from the pages URI to do this.
WinJS.UI.Pages.define("/showstuff.html", {
processed: function (element, options) {
var page = this;
WinJS.xhr(...).done(function (result) {
if (new Windows.Foundation.Uri(page.uri).path !== WinJS.Navigation.location)
return;
element.querySelector('#target').innerText = result.responseText;
});
}
};
I couldn't find an official way to do this, so I implemented a workaround.
WinJS.Navigation provides events that are fired on navigation. I used the navigating event to build a simple class that keeps track of page views:
var PageViewManager = WinJS.Class.define(
function () {
this.current = 0;
WinJS.Navigation.addEventListener('navigating',
this._handleNavigating.bind(this));
}, {
_handleNavigating: function (eventInfo) {
this.current++;
}
});
Application.pageViews = new PageViewManager();
The class increments a counter each time the user starts a new navigation.
With that counter, the Ajax request can check if any navigation occurred and react accordingly:
WinJS.UI.Pages.define("/showstuff.html", {
processed: function (element, options) {
var pageview = Application.pageViews.current;
WinJS.xhr(...).done(function (result) {
if (Application.pageViews.current != pageview)
return;
element.querySelector('#target').innerText = result.responseText;
});
}
};
I have this struct:
Example.Form = Ext.extend(Ext.form.FormPanel, {
// other element
, onSuccess:function(form, action) {
}
}
Ext.reg('exampleform', Example.Form);
Ext.onReady(function() {
var win = new Ext.Window({
id:'formloadsubmit-win'
,items:{id:'add', xtype:'exampleform'}
});
win.show();
})
I delete extra code above...
I want to do this: when I submit form on function-> onSuccess in Example.Form class able to close window on body. (When success results were submited and than the body of the window that opens become closed)
I apologize for my bad English.
The structure of the code should allow a place to store the components you are registering as xtypes. It should also have a top level namespace for the components that make up the app. This way you can always reference the parts of your app. It is also a good idea to break out the controller logic. For a small app, a single controller may work fine but once the app grows it is good to have many controllers for the app, one for each piece.
Here is a modified version of the code you put in that example. It will handle the success event and is structured to fit the recommendations noted above.
Ext.ns('Example');
/* store components to be used by app */
Ext.ns('Example.lib');
/* store instances of app components */
Ext.ns('Example.app');
Example.lib.Form = Ext.extend(Ext.form.FormPanel, {
// other element
// moved to app controller
//onSuccess:function(form, action) {
//}
});
Ext.reg('exampleform', Example.lib.Form);
Example.lib.FormWindow = Ext.extend(Ext.Window,{
initComponent: function(){
/* add the items */
this.items ={itemId:'add', xtype:'exampleform'};
/* ext js requires this call for the framework to work */
Example.lib.FormWindow.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('exampleformwin', Example.lib.FormWindow);
/*
manage/control the app
*/
Example.app.appController = {
initApp: function(){
Example.app.FormWindow = Ext.create({xtype:'exampleformwin', id:'formloadsubmit-win'});
Example.app.FormWindow.show();
/* get a reference to the 'add' form based on that item id and bind to the event */
Example.app.FormWindow.get('add').on('success', this.onAddFormSuccess, this );
},
/* the logic to handle the add-form's sucess event */
onAddFormSuccess: function(){
Example.app.FormWindow.hide();
}
}
Ext.onReady(function() {
/* start the app */
Example.app.appController.initApp()
})