cancel
Showing results for 
Search instead for 
Did you mean: 

SAPUI5 Add new entry from a form in the MockOData

Former Member
0 Kudos

Hello everybody,

I would like to add a new entry through a form in my OData model. And the new entry is immediately displayed in a List.

Now I have the OData by a mockServer and a form in a View to create the new entry.

Manifest.json is configured tow-way.

I have looked at the following document from sapui5 and Code from OpenSAPvideo.

https://sapui5.netweaver.ondemand.com/sdk/#docs/guide/6c47b2b39db9404582994070ec3d57a2.html

Code from OpenSap turorial Add.controller.js

		_onRouteMatched: function() {
			// register for metadata loaded events
			var oModel = this.getModel();
			oModel.metadataLoaded().then(this._onMetadataLoaded.bind(this));
		},
		
		_onMetadataLoaded: function () {
			// create default properties
			var oProperties = {
				ProductID: "" + parseInt(Math.random() * 1000000000),
				TypeCode: "PR",
				TaxTarifCode: 1,
				CurrencyCode: "EUR",
				MeasureUnit: "EA"
			};
			// create new entry in the model
			this._oContext = this.getModel().createEntry("/ProductSet", {
				properties: oProperties
			});
			// bind the view to the new entry
			this.getView().setBindingContext(this._oContext);
			
			// bind the view to the new entry
			//this.getView().setBindingContext(oContext);
		},

	_onCreateSuccess: function (oProduct) {
			// navigate to the new product's object view
			var sId = oProduct.ProductID;
			this.getRouter().navTo("object", {
				objectId : sId
			}, true);
	
			// unbind the view to not show this object again
			this.getView().unbindObject();
			
			// show success messge
			var sMessage = this.getResourceBundle().getText("newObjectCreated", [ oProduct.Name ]);
			MessageToast.show(sMessage, {
				closeOnBrowserNavigation : false
			});
		},

		/**
		 * Event handler for the save action
		 * @public
		 */
		onSave: function() {
			this.getModel().submitChanges();
		},

so this is my Calendarform.view.xml

<mvc:View
	controllerName="timeTrackertimeTracker.controller.Calendarform"
	xmlns="sap.m"
	xmlns:core="sap.ui.core"
	xmlns:mvc="sap.ui.core.mvc"
	xmlns:l="sap.ui.layout"
	xmlns:forms="sap.ui.layout.form"
	xmlns:me="sap.me">
    <l:Grid defaultSpan="L12 M12 S12" width="auto">
		<l:content>
			<forms:SimpleForm editable="true" layout="ResponsiveGridLayout" labelSpanL="3" labelSpanM="3" labelSpanS="4" emptySpanL="0" emptySpanM="0" id="form"
				emptySpanS="0" columnsL="2" columnsM="2">
				<forms:content>
					<Label text="ProjectNumber" />
					<Input value="{projectnumber}"
						id="projectnumber"
						placeholder="set a projectnumber"/>
					
					<Label text="Title"/>
					<Input value="{title}"
						id="title"
						placeholder="Set a Title"/>
					
					
					<Label text="Description"
					id="description"/>
					<TextArea value="{description}" 
						id="textarea"
						placeholder="Set your description"/>
					
					<Label text="Starttime"/>
					<DateTimePicker
					id="startime"
					value="{starttime}"
					width="100%"
					placeholder="Set Starttime"
					class="sapUiTinyMarginBottom" />
					
					<Label text="Endtime"/>
					<DateTimePicker
					id="endtime"
					value="{endtime}"
					width="100%"
					placeholder="Set EndTime"
					class="sapUiTinyMarginBottom" />
					
					<Label text="resttime"/>
					<Input type="Number"
						id="resttime"
						value="{resttime}"
						placeholder="please enter only a Number"/>
			    	<Toolbar>
						<ToolbarSpacer/>
						<Button
						text="{i18n>save}"
						type="Accept"
						id="save"
						press="onSave"/>
						<Button
						text="{i18n>cancel}"
						type="Reject"
						id="cancel"
						press="onCancel"/>
					</Toolbar>
				</forms:content>
			</forms:SimpleForm>
		</l:content>
    </l:Grid>
</mvc:View>

And this is my AppointmentsList.view.xml

<mvc:View
    	controllerName="timeTrackertimeTracker.controller.DateRange"
    	xmlns:l="sap.ui.layout"
    	xmlns:mvc="sap.ui.core.mvc"
    	xmlns="sap.m" >

        <Title  text="{i18n>appTitle}" titleStyle="Auto"  textAlign="Begin" visible="true"/>

    	<mvc:XMLView viewName="timeTrackertimeTracker.view.DateRange"/>
    	
					<Table
						id="listTracker"
						width="auto"
						items="{appointments>/appointments}"
						growing="true"
						growingScrollToLoad="true">
					<headerToolbar>
						<Toolbar>
							<Title id="tableHeader" text="Tracker Title"/>
						</Toolbar>
					</headerToolbar>
						<columns>
							<Column id="projecTitleColumn">
								<Text text="{i18n>trackerTitle}" id="projectTitleColumnText"/>
							</Column>
							<Column id="projecNumberColumn">
								<Text text="{i18n>projectnumber}" id="projectNumberColumnText"/>
							</Column>
							<Column
								id="startTimeColumn">
								<Text text="{i18n>startTime}"/>
							</Column>
							<Column
								id="endTimeColumn">
								<Text text="{i18n>endTime}"/>
							</Column>
							<Column
								id="restTime">
								<Text text="Rest Time"/>
							</Column>
							<Column
								id="durationColumn">
								<Text text="Duration"/>
							</Column>
							<Column
								id="flag">
								<Text text="Billable"/>
							</Column>
							<Column id="description" hAlign="End">
								<Text text="{i18n>description}" id="descriptionColumn"/>
							</Column>
							<Column id="actionColumn" hAlign="End">
								<Text text="{i18n>delete}" id="actionColumnTitle"/>
							</Column>
						</columns>
						<items>
							<ColumnListItem>
								<cells>
									<ObjectListItem
										title="{appointments>title}"/>
									<ObjectIdentifier
										title="{appointments>Id}"
										text="{appointments>projektnummer}"
										titleActive="true"
										titlePress="onShowDetailPopover"/>
									<Text text="{appointments>starttime}"/>
									<Text text="{appointments>endtime}"/>
									<ObjectIdentifier
										text="{appointments>rest}"
										/>
									<ObjectIdentifier
										text="{appointments>starttime} x {appointments>endtime}"
										/>
									<ObjectListItem
										markFlagged="{appointments>flag}"
										title="{appointments>flag}"
										/>
									<Text text="{appointments>description}"/>
									<Button id="delete" press="onDeleteProduct" icon="sap-icon://delete"/>
								</cells>
							</ColumnListItem>
						</items>
					</Table>
    </mvc:View>

the OData come from my MockServer.

first i have included the odata model in my Calendarform.controller.js

sap.ui.define(['sap/ui/core/mvc/Controller', 
	'timeTrackertimeTracker/controller/BaseController', 
	'sap/ui/model/json/JSONModel', 
	"sap/m/MessageToast",
	//"sap/ui/model/odata/ODataModel",
	"sap/ui/model/odata/v2/ODataModel"
	],

    	function(Controller, MessageToast, JSONModel, ODataModel) {
    	"use strict";
    	
    	//Global variables
    	var _oController, oModel, oView;
    	
 		//var starttimeVal, endtimeVal, oModel , textAreaVal;
    	var Calendarcontroller = Controller.extend("timeTrackertimeTracker.controller.Calendarform", {
    	
		/* =========================================================== */
		/* lifecycle methods                                           */
		/* =========================================================== */
    		
		onInit: function() {
				//Store controller reference to global variable
				_oController = this; 
				oView = this.getView();
		},
		
		/* =========================================================== */
		/* event handlers                                              */
		/* =========================================================== */
	onSave: function(oEvent) {

           var oProperties = {
				Id: "Id" + parseInt(Math.random() * 1000000000),
				projectnumber: "",
				//endtime - starttime in stunden ist duration
				duration: "",
				resttime: "",
				title: "",
				starttime: "",
				endtime: "",
				Description: ""
			};
			// create new entry in the model
			this._oContext = this.getView().getModel().createEntry("appointments>/appointments", {
				properties: oProperties,
				success: this._onCreateSuccess.bind(this)
			});
			// bind the view to the new entry
			this.getView().setBindingContext(this._oContext);
			this.getView().getModel().submitChanges();
			
			this.getView()._onCreateSuccess();
		}, 
		
		_onCreateSuccess: function (oAppointment) {
			// show success messge
			var sMessage = this.getResourceBundle().getText("newObjectCreated", [ oAppointment.Title ]);
			MessageToast.show(sMessage, {
				closeOnBrowserNavigation : false
			});
		},
    		
		onCancel: function() {
			this.getView().getModel().deleteCreatedEntry(this._oContext);
		}
    	});
     
    	return Calendarcontroller;
     
    });

and i changed my matadeta.xml

<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
	<edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0"
					   xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
		<Schema Namespace="timeTrackertimeTracker" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
			<EntityType Name="appointments">
				<Key>
					<PropertyRef Name="Id"/>^
					<PropertyRef Name="projektnummer"/>
				</Key>
				<Property Name="Id" Type="Edm.String" Nullable="true" />
				<Property Name="projektnummer" Type="Edm.String" Nullable="true" />
				<Property Name="title" Type="Edm.String" Nullable="false" />
				<Property Name="starttime" Type="Edm.DateTime" Nullable="false" />
			    <Property Name="endtime" Type="Edm.DateTime" Nullable="false" />
			    <Property Name="duration" Type="Edm.Int16" MaxLength="2" Nullable="false" />
			    <Property Name="rest" Type="Edm.Byte" Precision="16" Scale="3" MaxLength="2" Nullable="false" />
			    <Property Name="flag" Type="Edm.Boolean" Nullable="false" />
				<Property Name="description" Type="Edm.String" Nullable="false"/>
			</EntityType>
		</Schema>
		<Schema Namespace="timeTrackertimeTracker.Model" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
			<EntityContainer Name="timeTrackertimeTrackerEntities" m:IsDefaultEntityContainer="true" p6:LazyLoadingEnabled="true"
							 xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
				<EntitySet Name="appointments" EntityType="timeTrackertimeTracker.appointments"/>
			</EntityContainer>
		</Schema>
	</edmx:DataServices>
</edmx:Edmx>

And in this BaseController.js is v2/ODataModel actually already imported.

I would like to add now a new entry through a form in my OData model. And the new entry should appear immediately in the Appointmentslist..

Now I try to add the new entry directly with "this" in ODATA

What i want to do now is that, I must first assign the data from the form-element to a property or variable, then add this variable or property with createEntry to a new entry in oModel() in this Object.

My frist question: How can i get and set the content from the form, if the save button is clicked and onSave Event trigged ?

second: How can i set the date from the Form to the oModel.

And currently I have a problem. Although v2OModelData is already imported, but createEntry and deleteCreatedEntry is displaying the Error in the console

"Uncaught TypeError: Cannot read property 'createEntry' of undefined"

"Uncaught TypeError: Cannot read property 'deleteCreatedEntry' of undefined"

Is they any error with the import or call to the createEntry?

thanks very so much!!!

Accepted Solutions (0)

Answers (1)

Answers (1)

former_member365727
Active Contributor
0 Kudos

is your model avilable in the view controller or at component level?

from the error it is clear that 'this.getModel()' is not able to retrieve model.....which results in 'undefined' that gives the error "Uncaught TypeError: Cannot read property 'createEntry' of undefined"