I have a details view from where I load a modal popup as below;
var modal = new MyModalView({
model: person
});
My modal view looks as below;
define([
'base/BaseModalView'
], function(BaseModalView) {
var MyModal = BaseModalView.extend({
el: "#myModalContainer",
initialize: function() {
this._initAndRenderModal(myModalTemplate, {
model: this.model.toJSON()
});
},
render: function() {
var self = this;
self.personModel = new Person({
"personId": $('#personName option:selected').data('personid'),
"personName": $('#personName').val()
});
self.populatePersons();
},
populatePersons: function() {
var self = this,
$personName = $('#personName', this.el);
$personName.attr('disabled', 'disabled').html('<option value="">Loading Persons...</option>');
self.personCollection.fetch({
success: function() {
var personList = self.personCollection.toJSON(),
aOptions = '<option value="">- Select -</option>',
l = personList.length;
if (l)
{
for (var i = 0; i < l; ++i)
{
var val = _.escape(personList[i].personName);
aOptions += '<option value="' + _.escape(personList[i].personName) + '" data-personid="' + _.escape(personList[i].personId) + '" title="' + val + '">' + val + '</option>';
}
$personName.removeAttr('disabled').html(aOptions);
}
else
{
$personName.html('<option>No Person available</option>');
}
if (self.model.get("personId") != null) {
$personName.val(self.model.attributes.person.attributes.personName);
$personName.attr("disabled", "disabled");
}
}
});
},
saveAction: function(event) {
var self = this;
var checkPerson = self.personModel.validateAll();
var invalid = !checkPerson.isValid;
if (invalid) {
if (!checkPerson.isValid) {
self.showValidationErrors(checkPerson.messages);
}
return true;
}
return false;
}
});
return MyModal;
});
My question is in the Edit mode,
self.personModel is having null values
when I save the form, since the below code is called after the values are set;
self.personModel = new Person({
"personId": $('#personName option:selected').data('personid'),
"personName": $('#personName').val()
});
How do I fix this?
Related
I am developing a web application which tries to upload a file to a server.
I attempted to create a new ViewModel object, but it still says
undefined
This is my ojprogresslist.js:
"use strict";
define(['ojs/ojcore', 'jquery', 'knockout', 'ojs/ojcomposite','resources/components/file-upload-custom/viewModel.js', 'ojs/ojknockouttemplateutils','ojs/ojcomponentcore', 'ojs/ojlistview', 'ojs/ojprogress'],
function(oj, $, ko, Composite, viewModel, KnockoutTemplateUtils)
{
var deleteButton=
" <oj-button id='btn1' chroming='half' display='icons' on-oj-action='[[deleteItem]]'>"+
" <span class='oj-component-icon oj-panel-remove-icon'></span>"+
"</oj-button>";
var progressItemView =
" <div class='oj-flex oj-sm-justify-content-space-between'>" +
" <div class='oj-flex-item oj-flex oj-sm-flex-direction-column'>" +
" <span data-bind='text: $properties.data.name' class='oj-progresslist-name'></span>" +
" <div data-bind='text: message' class='oj-progresslist-error-message'></div>" +
' </div>' +
" <div class='oj-flex oj-sm-align-items-center'>" +
" <oj-bind-slot name='itemInfo'>" +
" <div class='oj-flex-item oj-flex oj-progresslist-info'>" +
" <span data-bind='text: $data.getSizeInBKMGT($properties.data.size)'></span>" +
' </div>' +
' </oj-bind-slot>' +
" <div class='oj-flex-item oj-flex'>" +
" <oj-progress-status status='{{status}}'" +
" progress='{{progress}}'>" +
' </oj-progress-status>' +
' </div>' +
' </div>' +
deleteButton +
' </div>';
function progressItemViewModel(context) {
var self = this;
this.deleteItem=function(event){
viewModel.deleteList(); // this is undefined
};
};
This is my fileCustom.js:
define([
'knockout',
'ojs/ojcore',
'jquery', 'ojs/ojarraydataprovider', 'fileUploadTransport/MockTransport', 'fileUploadTransport/MockUploadXhr',
'fileUploadTransport/MockTransportItem', 'ojs/ojknockout', 'ojs/ojtoolbar', 'ojs/ojbutton', 'ojs/ojfilepicker', 'resources/js/ojprogresslist'],
function (ko, oj, $, ArrayDataProvider, Transport, MockUploadXhr) {
'use strict';
function ComponentModel(context) {
var self = this;
self.noData = ko.observable(true);
self.isSimulateError = ko.observableArray([]);
self.koArray = ko.observableArray([]);
//create file upload data provider
self.dataProvider = new ArrayDataProvider(self.koArray, {keyAttributes: 'item'});
//add or remove files
self.dataProvider.addEventListener('mutate', function(event) {
if (event.detail.add != null) {
self.noData(false); // enable clear button
}
else if (event.detail.remove != null) {
self.dataProvider.getTotalSize().then(function(size) {
if (size == 0) {
self.noData(true); //disable clear button
}
});
}
});
var options = {
maxChunkSize: 3000000, //for chunkupload
xhr: MockUploadXhr
};
var transport = new Transport(options);
self.status = 200;
function getStatus() {
if (self.isSimulateError().length) {
self.status = (self.status !== 401) ? 401 : 405;
}
else {
self.status = 200;
}
return self.status;
};
//add a filesAdd listener for upload files
self.selectListener = function(event) {
var files = event.detail.files;
if (files.length > 0) {
var fileItems = transport.queue(files);
//add the new files at the beginning of the list
for (var i = 0; i < fileItems.length; i++)
{
self.koArray.unshift(fileItems[i]);
}
//simulate error status
transport.setErrorStatus(getStatus());
//upload files
transport.flush();
}
};
//clear file items from the data provider
self.filterRemove = function(statusList) {
var dataProvider = self.dataProvider;
//remove all data rows
if (! statusList || statusList.length == 0) {
return self.koArray.removeAll();
}
var statuses = {};
for (var i = 0; i < statusList.length; i++) {
statuses[statusList[i]] = true;
}
//In this demo we only fetch up to 25 data rows,
//however you can fetch any number of rows that is right for your app
var asyncIterable = dataProvider.fetchFirst({size:25})[Symbol.asyncIterator]();
return asyncIterable.next().then(
function (fetchResults) {
var data = fetchResults.value.data;
for (var i = 0; i < data.length; i++) {
var progressItem = data[i];
if (statuses[progressItem.status])
self.koArray.remove(progressItem);
}
})
};
//clear file items from the progress list
self.clearProgressList = function(event) {
console.log("hello world"+event);
self.filterRemove(['loaded', 'errored']);
};
self.deleteList = function() {
console.log("hello world");
self.filterRemove(['loaded', 'errored']);
};
}
return ComponentModel;
});
This is my HTML:
<div style="padding-top:10px"></div>
<label for="progressList">File Upload Status</label>
<div style="padding-top:5px"></div>
<oj-progress-list id="progressList" data="[[dataProvider]]">
</oj-progress-list>
</div>
I am calling viewModel.deleteList(); from the ojprogresslist.js file to filecustom.js. And I need to call the deleteList function to delete items from ArrayDataProvider.
But the error I get is
undefined
Can you please help me?
Looking through the code for the viewModel you are returning the function ComponentModel without ever calling the method (I can't remember off the top of my head if requirejs does this for you). so my guess is that the progressItemViewModel in ojprogresslist.js
should probably look like
function progressItemViewModel(context) {
var self = this;
this.deleteItem=function(event){
//not sure if the context that is passed in to the parent function is what is expected by the ComponentModel.
//so the call may be viewModel().deleteList();
viewModel(context).deleteList();
};
};
The other thing to note is that you are not using context in function ComponentModel(context){...}.
For the life of me I cannot see the suttle difference between copied code. The _getMiscData method in a child widget apparently doesn't exist according to the parent widget. Can someone explain this?
I tried different method names in case I was using a reserved word. I tried private and public method with same result.
$(function() {
$.widget("custom.textquestion", $.custom.base, {
_create: function() {
this.element.data("_getControlValue", this.getControlValue());
},
getControlValue: function() {
this.element.attr("usersanswer", this.getResponseJSON());
},
_getAnswerSelection: function(answer) {
var qname = this._getQuestionName();
var type = this.getType();
return '<div class="radio span6"><label><input type="text" class="answerfield" name="optradio-' + qname + '" value="' + answer.answertext + '"></label></div>'
},
_getAnswersDiv: function(answers) {
// DIV is required for wrapping around list of answers
// so that they can be added all at once.
var answerdivs = '<div class="answerlist">'
for (k = 0; k < answers.length; k++) {
answerdivs += this._getAnswerSelection(answers[k]);
}
answerdivs += '</div>';
return answerdivs;
},
_getPopulatedEditor: function(answers) {
var editanswerdiv = "";
for (p = 0; p < answers.length; p++) {
editanswerdiv += '<label>Default</label><input type="text" onblur="savequestiondata()" identifier="' + answers[p].answerid + '" name="editanswer' + this._getQuestionName(this.options.questioncontrol) + '" size="20" value="' + answers[p].answertext + '"/><br/>'
}
return editanswerdiv;
},
_getAnswersJSON: function(div) {
var answers = [];
$(div).find("input[name='editanswer" + this._getQuestionName(this.options.questioncontrol) + "']").each(function(i, u) {
var answer = {
answerid: $(this).attr('identifier'),
answertext: $(this).val(),
answerorder: 0,
rating: 0
};
answers.push(answer);
});
return answers;
},
_setAnswerJSON: function(answer) {
answer = answer.replace(/['"]+/g, '');
this.options.questioncontrol.find("input[name='optradio-" + this._getQuestionName() + "']").val(answer);
return true;
},
getResponseJSON: function() {
qname = this._getQuestionName();
console.log("The control name is " + qname);
var answer = this.options.questioncontrol.find("input[name='optradio-" + qname + "']").val();
console.log("The answer is " + answer);
return answer;
},
_refresh: function() {
qname = this._getQuestionName(this.options.questioncontrol);
// Create the divs for the answer block, then
// append to this question as the list of answers.
var answers = this._getStoredData().data.answers;
var answerhtml = this._getAnswersDiv(answers);
this.options.questioncontrol.find(".answer-list").html("");
this.options.questioncontrol.find(".answer-list").append(answerhtml);
// Get the explanation text and add to control.
var explanation = this._getStoredData().data.explanation;
this.options.questioncontrol.find(".explanation").text(explanation);
// Populate the editor controls with the answers that
// are already stored - ready for editing.
var editanswerhtml = this._getPopulatedEditor(answers);
this.options.questioncontrol.find(".editanswers").html("");
this.options.questioncontrol.find(".editanswers").append(editanswerhtml);
this.options.questioncontrol.find(".notes").text(explanation);
},
_getQuestionText: function(div) {
var qtext;
$(div).find("input[name='questiontextedit']").each(function() {
qtext = $(this).val();
});
return qtext;
},
_getMiscData: function() {
var info = [this.options.questioncontrol.find(".email-mask").val()];
return info;
},
_setOtherData: function(info) {
if (info.emailmask == "true")
this.options.questioncontrol.find(".email-mask").attr("checked", "checked");
else
this.options.questioncontrol.find(".email-mask").attr("checked", "");
},
_getExplanationText: function(div) {
var etext = $(div).find(".notes").val();
return etext;
}
});
});
$(function() {
$.widget("custom.base", {
// default options
options: {
questioncontrol: this,
questiondata: null,
_storedData: [],
},
_create: function() {
},
_refresh: function() {
},
getEditedAnswers: function(div) {
// Get the set of answers that were edited.
if (!div)
div = this.options.questioncontrol;
var answersresult = this._getAnswersJSON(div);
var question = this._getQuestionText(div);
var typename = this.getType();
var qname = this._getQuestionName(this.options.questioncontrol);
var pagenumber = this._getStoredData(qname).data.pagenumber;
var order = this._getStoredData(qname).data.order;
var explanation = this._getExplanationText(div);
var otherdata = this._getMiscData();
var result = {
title: question,
type: typename,
pageid: pagenumber,
qname: qname,
answers: answersresult,
questionorder: order,
explanation: explanation,
otherdata: otherdata
};
return result;
},
getType: function() {
return $(this.options.questioncontrol).attr('id');
},
setData: function(questiondata) {
// Set the title for the question. I.e, the text
// for the question.
this.options.questioncontrol.find(".questiontitle").text(questiondata.title);
this.options.questioncontrol.find("input[name='questiontextedit']").val(questiondata.title);
this.options.questioncontrol.find(".notes").text(questiondata.explanation);
// Store the data into datastore.
var stored = 0;
if (this._getStoredData(questiondata.qname) == null) {
this.options._storedData.push({
qname: questiondata.qname,
data: questiondata
});
} else {
var datastored = this._getStoredData(questiondata.qname);
datastored.data = questiondata;
}
if (questiondata.otherdata)
this._setOtherData(questiondata.otherdata);
this._refresh();
},
setAnswer: function(answer) {
this._setAnswerJSON(answer);
},
_getQuestionName: function() {
return this.options.questioncontrol.find('.questionname').val();
},
_getStoredData: function() {
var qname = this._getQuestionName(this.options.questioncontrol);
for (p = 0; p < this.options._storedData.length; p++) {
if (this.options._storedData[p].qname == qname)
return this.options._storedData[p];
}
return null;
},
});
});
The custom.base widget shouldn't return with "this.getMiscData is not a function"
I am trying to develop a Fiori app using sap.m.planningcalendar control. My default model is ODataModel.V2 which I provide from SAP backend. Everything seemed to be normal until I decided to implement DnD functionality which comes with ui5 version 1.56.
The sample has an example code like below;
handleAppointmentDropBetweenRows = function () {
var aPath = oAppBindingContext.getPath().split("/"),
iIndex = aPath.pop(),
sRowAppointmentsPath = aPath.join("/");
oRowBindingContext.getObject().appointments.push(
oModel.getProperty(oAppBindingContext.getPath())
);
oModel.getProperty(sRowAppointmentsPath).splice(iIndex, 1);
};
This is not working in my case. So instead, i am adding new appointment;
oCalendarRow.addAppointment(oAppointment);
Although, if I create a new JSON model and set the data, this is working fine, but if I use the OData.v2 model coming from the backend as the default model, it throws an error like below;
Error: adding element with duplicate id '__appointment0-__row0-__xmlview0--PC1-0-96'*
Error-screenshot
I couldn't find any example for sap.m.planningcalendar with a backend scenario with drag&drop functionality.
So any suggestions ?
P.S : I have also tried adding templateShareable: 'false' for PlanningCalendarRows in the view like below;
appointments="{path : 'to_MaintOrderOper', templateShareable: 'false'}"
Also didn't work.
Best regards
My view;
<mvc:View controllerName="ZPM.ZPM_CAPACITY_PLAN.controller.Main" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core" xmlns:unified="sap.ui.unified" xmlns:modeltype="sap.ui.model.type" xmlns="sap.m">
<App id="idAppControl">
<pages>
<Page title="{i18n>title}">
<content>
<VBox class="sapUiSmallMargin">
<PlanningCalendar id="PC1" rows="{path: '/ZPM_C_CAPACITY_PLAN2', parameters:{expand:'to_MaintOrderOper'}, templateShareable: 'false'}" appointmentsVisualization="Filled"
appointmentSelect="handleAppointmentSelect">
<toolbarContent>
<Title text="{i18n>toolbarTitle}" titleStyle="H4"/>
<ToolbarSpacer/>
<Button
id="saveButton"
text="{i18n>save}"
type="Emphasized"
icon="sap-icon://save"
press="handleSaveChanges"
tooltip="{i18n>submit}"/>
<Label text="Logged in as"/>
<Select
id="userRole"
change="handleRoleChange"
selectedKey="admin"
width="230px">
<items>
<core:Item key="admin" text="Admin"/>
<core:Item key="manager" text="Manager"/>
<core:Item key="donna" text="Donna Moore"/>
</items>
</Select>
</toolbarContent>
<rows>
<PlanningCalendarRow
title="{EmployeeFullName}"
text="{Skill}"
icon="{EmployeePic}"
enableAppointmentsDragAndDrop="{path:'EmployeeFullName', formatter:'.canModifyAppointments'}"
enableAppointmentsResize="{path:'EmployeeFullName', formatter:'.canModifyAppointments'}"
appointmentDrop="handleAppointmentDrop"
appointmentDragEnter="handleAppointmentDragEnter"
appointmentResize="handleAppointmentResize"
appointmentCreate="handleAppointmentCreate"
appointments="{path : 'to_MaintOrderOper', templateShareable: 'false'}">
<appointments>
<unified:CalendarAppointment
startDate="{path: 'StartDateTime2', type: 'sap.ui.model.type.DateTimeOffset'}"
endDate="{path: 'EndDateTime2', type: 'sap.ui.model.type.DateTimeOffset'}"
icon="{PlanningIcon}"
title="{Title}"
text="{Info}">
</unified:CalendarAppointment>
</appointments>
</PlanningCalendarRow>
</rows>
</PlanningCalendar>
</VBox>
</content>
</Page>
</pages>
</App>
Also my controller;
/*eslint-disable*/
sap.ui.define(['jquery.sap.global',
'sap/m/MessageBox',
'sap/m/Button',
'sap/m/Dialog',
'sap/m/Label',
'sap/m/Popover',
'sap/m/List',
'sap/m/StandardListItem',
'sap/ui/core/Fragment',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel',
'sap/m/MessageToast'
],
function (jQuery, MessageBox, Button, Dialog, Label, Popover, List, StandardListItem, Fragment, Controller, JSONModel, MessageToast) {
"use strict";
return Controller.extend("ZPM.ZPM_CAPACITY_PLAN.controller.Main", {
onInit: function () {
},
toDateObject: function (sDateString) {
var oAppointmentDate = new Date(sDateString);
return oAppointmentDate;
},
roles: {
donna: "Donna Moore",
manager: "manager",
admin: "admin"
},
handleRoleChange: function () {
this.getView().getModel().refresh(true);
},
getUserRole: function () {
return this.roles[this.byId("userRole").getSelectedKey()];
},
canModifyAppointments: function (sRole) {
var sUserRole = this.getUserRole();
if (sUserRole === this.roles.manager || sUserRole === this.roles.admin || sUserRole === sRole) {
return true;
}
},
// New functionality to show detailed popover for Jobs
handleAppointmentSelect: function (oEvent) {
debugger;
var oJobDetails = new sap.ui.model.json.JSONModel();
var oAppointment = oEvent.getParameter("appointment");
var oTitle = oAppointment.getTitle();
var oIcon = oAppointment.getIcon();
var oStartDateText = this._oResourceBundle().getText("startDate");
var oStartDate = oAppointment.getStartDate();
var oEndDateText = this._oResourceBundle().getText("endDate");
var oEndDate = oAppointment.getEndDate();
var oJobInfoText = this._oResourceBundle().getText("jobInfo");
var oJobInfo = oAppointment.getText();
var mJobDetails = {
pages: [{
pageId: "jobDetailsPageId",
title: oTitle,
icon: oIcon,
groups: [{
elements: [{
label: oStartDateText,
value: oStartDate
}, {
label: oEndDateText,
value: oEndDate
}, {
label: oJobInfoText,
value: oJobInfo
}]
}]
}]
};
// set the data for the model
oJobDetails.setData(mJobDetails);
// Now open QuickView
this.openQuickView(oAppointment, oJobDetails);
},
openQuickView: function (oAppointment, oJobDetails) {
this.createPopover();
this._oQuickView.setModel(oJobDetails, "oJobDetailsModel");
this._oQuickView.openBy(oAppointment);
},
createPopover: function () {
if (this._oQuickView) {
this._oQuickView.destroy();
}
this._oQuickView = sap.ui.xmlfragment("ZPM.ZPM_CAPACITY_PLAN.view.JobDetails", this);
this.getView().addDependent(this._oQuickView);
},
handleAppointmentDragEnter: function (oEvent) {
if (this.isAppointmentOverlap(oEvent, oEvent.getParameter("calendarRow"))) {
oEvent.preventDefault();
}
},
onQuickviewClose: function (oEvent) {
if (this._oQuickView) {
this._oQuickView.destroy();
}
//oEvent.getParameters().openBy.setSelected(false);
},
handleAppointmentDrop: function (oEvent) {
debugger;
var oAppointment = oEvent.getParameter("appointment"),
oStartDate = oEvent.getParameter("startDate"),
oEndDate = oEvent.getParameter("endDate"),
oCalendarRow = oEvent.getParameter("calendarRow"),
bCopy = oEvent.getParameter("copy"),
oModel = this.getView().getModel(),
oAppBindingContext = oAppointment.getBindingContext(),
oRowBindingContext = oCalendarRow.getBindingContext();
/* handleAppointmentDropBetweenRows = function () {
var aPath = oAppBindingContext.getPath().split("/"),
iIndex = aPath.pop(),
sRowAppointmentsPath = aPath.join("/");
oCalendarRow.addAppointment(oAppointment)
oRowBindingContext.getObject().appointments.push(
oModel.getProperty(oAppBindingContext.getPath())
);
oModel.getProperty(sRowAppointmentsPath).splice(iIndex, 1);
};*/
if (bCopy) { // "copy" appointment
var oProps = jQuery.extend({}, oModel.getProperty(oAppointment.getBindingContext().getPath()));
oProps.start = oStartDate;
oProps.end = oEndDate;
oRowBindingContext.getObject().appointments.push(oProps);
} else { // "move" appointment
//oModel.setProperty("start", oStartDate, oAppBindingContext);
//oModel.setProperty("end", oEndDate, oAppBindingContext);
oAppointment.setStartDate(oStartDate);
oAppointment.setEndDate(oEndDate);
oAppointment.setType("Type03");
if (oAppointment.getParent() !== oCalendarRow) {
debugger;
oCalendarRow.addAppointment(oAppointment);
//handleAppointmentDropBetweenRows();
}
}
MessageToast.show(oCalendarRow.getTitle() + "'s '" + "Appointment '" + oAppointment.getTitle() + "' now starts at \n" + oStartDate +
"\n and end at \n" + oEndDate + ".");
},
handleAppointmentResize: function (oEvent) {
var oModel = this.getView().getModel();
var oAppointment = oEvent.getParameter("appointment"),
oStartDate = oEvent.getParameter("startDate"),
oEndDate = oEvent.getParameter("endDate");
var dateFormat = sap.ui.core.format.DateFormat.getDateInstance({pattern : "yyyy-MM-ddTHH:mm:ss" });
if (!this.isAppointmentOverlap(oEvent, oAppointment.getParent())) {
MessageToast.show("Appointment '" + oAppointment.getTitle() + "' now starts at \n" + oStartDate + "\n and end at \n" + oEndDate +
".");
// oModel.setProperty("StartDateTime2", dateFormat.format(oStartDate) , oAppointment.getBindingContext());
// oModel.setProperty("EndDateTime2", dateFormat.format(oEndDate) , oAppointment.getBindingContext());
oAppointment.setStartDate(oStartDate);
oAppointment.setEndDate(oEndDate);
oAppointment.setType("Type03");
} else {
MessageToast.show("As a manager you can not resize events if they overlap with another events");
}
},
// Our App should not support Appointment Creation
/*handleAppointmentCreate: function (oEvent) {
var oStartDate = oEvent.getParameter("startDate"),
oEndDate = oEvent.getParameter("endDate"),
oPlanningCalendarRow = oEvent.getParameter("calendarRow"),
oModel = this.getView().getModel(),
sPath = oPlanningCalendarRow.getBindingContext().getPath();
oModel.getProperty(sPath).appointments.push({
title: "New Appointment",
start: oStartDate,
end: oEndDate
});
MessageToast.show("New Appointment is created at \n" + oStartDate + "\n and end at \n" + oEndDate + ".");
oModel.refresh(true);
},*/
isAppointmentOverlap: function (oEvent, oCalendarRow) {
var oAppointment = oEvent.getParameter("appointment"),
oStartDate = oEvent.getParameter("startDate"),
oEndDate = oEvent.getParameter("endDate"),
bAppointmentOverlapped;
if (this.getUserRole() === this.roles.manager) {
bAppointmentOverlapped = oCalendarRow.getAppointments().some(function (oCurrentAppointment) {
if (oCurrentAppointment === oAppointment) {
return;
}
var oAppStartTime = oCurrentAppointment.getStartDate().getTime(),
oAppEndTime = oCurrentAppointment.getEndDate().getTime();
if (oAppStartTime <= oStartDate.getTime() && oStartDate.getTime() < oAppEndTime) {
return true;
}
if (oAppStartTime < oEndDate.getTime() && oEndDate.getTime() <= oAppEndTime) {
return true;
}
if (oStartDate.getTime() <= oAppStartTime && oAppStartTime < oEndDate.getTime()) {
return true;
}
});
}
return bAppointmentOverlapped;
},
handleSaveChanges: function (oEvent) {
var oModel = this.getView().getModel(),
bError = false;
// abort if the model has not been changed
if (!oModel.hasPendingChanges()) {
var bCompact = !!this.getView().$().closest(".sapUiSizeCompact").length;
MessageBox.information(
this._oResourceBundle().getText("noChangesMessage"), {
styleClass: bCompact ? "sapUiSizeCompact" : ""
}
);
return;
}
oModel.submitChanges();
},
_checkIfBatchRequestSucceeded: function (oEvent) {
var oParams = oEvent.getParameters();
var aRequests = oEvent.getParameters().requests;
var oRequest;
if (oParams.success) {
if (aRequests) {
for (var i = 0; i < aRequests.length; i++) {
oRequest = oEvent.getParameters().requests[i];
if (!oRequest.success) {
return false;
}
}
}
return true;
} else {
return false;
}
},
_fnUpdateSuccess: function () {
this.getView().setBusy(false);
this.getView().unbindObject();
this.getRouter().getTargets().display("object");
},
_oResourceBundle: function() {
var oBundle = this.getView().getModel("i18n").getResourceBundle();
return oBundle;
}
});
});
I am wondering me how I do that, because all the time the variable returns to your default value. It's an Ibeacon application, I don't know if I need to show more details about my app. I just want to call the function something once, can anyone help me?
function uint8ArrToHexStringNoSpace(arr) {
return Array.prototype.map.call(arr, function(n) {
var s = n.toString(16);
if(s.length == 1) {
s = '0'+s;
}
return s;
}).join('');
}
var quit;
function something() {
if(quit) {
window.open("info.html");
}
quit = true;
}
function appendTd(root, value, id) {
var text = document.createTextNode(value);
var td = document.createElement("p");
if(id) {
td.id = id;
}
td.appendChild(text);
root.appendChild(td);
}
function hex16(i) {
var s = i.toString(16);
while(s.length < 4) {
s = '0'+s;
}
return s;
}
var beacons = {};
var app = {
initialize: function() {
// Important to stop scanning when page reloads/closes!
window.addEventListener('beforeunload', function(e)
{
iBeacon.stopScan();
});
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function() {
//app.receivedEvent('deviceready');
app.startScan();
},
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
},
startScan: function() {
iBeacon.startScan({}, function(beacon) {
//console.log("beacon found: "+beacon.address+" "+beacon.name+" "+beacon.rssi+"/"+beacon.txPower);
var r = beacon.region;
//console.log("M"+r.major.toString(16)+" m"+r.minor.toString(16)+" uuid "+uint8ArrToHexStringNoSpace(r.uuid));
var key = 'tx'+beacon.address.replace(/:/g,'_');
//console.log('key: '+key);
if(beacons[key] == null) {
beacons[key] = beacon;
var root = document.getElementById("beaconListRoot");
var tr = document.createElement("tr");
var br = document.createElement("br");
// <tr><td>Address</td><td>Name</td><td>RSSI</td><td>ID</td><td>UUID</td></tr>
var adress = ' Adress: ';
var name = ' Name: ';
var distance = ' distance: ';
var major = ' Major: ';
var minor = 'Minor: ';
var UUID = ' UUID: ';
appendTd(tr, adress + beacon.address + name + beacon.name);
appendTd(tr, distance + beacon.rssi+" /"+beacon.txPower+"\u00A0"+beacon.estimatedDistance.toFixed(2)+'m', key);
appendTd(tr, major + hex16(r.major)+"\u00A0"+ minor +hex16(r.minor));
appendTd(tr, UUID + uint8ArrToHexStringNoSpace(r.uuid));
root.appendChild(tr);
} else {
var td = document.getElementById(key);
td.firstChild.nodeValue = 'Power: ' + beacon.rssi+"/"+beacon.txPower+ ' Distance: ' + "\u00A0"+beacon.estimatedDistance.toFixed(2)+'m';
}
if(beacon.address == '78:A5:04:13:3B:17' && beacon.estimatedDistance.toFixed(2) <= 10 ){
something();
}
}, function(error) {
console.log("startScan error: " + error);
});
},
};
use localStorage: https://developer.mozilla.org/en/docs/Web/API/Window/localStorage
localStorage (and sessionStorage) let you keep persistent values
function something() {
localStorage.setItem("somethingCalled", "yes");
if(quit) {
window.open("info.html");
}
quit = true;
}
then where you call something():
if (localStorage.getItem("somethingCalled")!="yes") {
something()
}
you may whant to use sessionStorage instead of localStorage (https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage)
I'm using this autocomplete code to be able to pull stock information:
var YAHOO = {};
YAHOO.util = {};
YAHOO.util.ScriptNodeDataSource = {};
var stockSymbol;
var compName;
YUI({
filter: "raw"
}).use("datasource", "autocomplete", "highlight", function (Y) {
var oDS, acNode = Y.one("#ac-input");
oDS = new Y.DataSource.Get({
source: "http://d.yimg.com/aq/autoc?query=",
generateRequestCallback: function (id) {
YAHOO.util.ScriptNodeDataSource.callbacks =
YUI.Env.DataSource.callbacks[id];
return "&callback=YAHOO.util.ScriptNodeDataSource.callbacks";
}
});
oDS.plug(Y.Plugin.DataSourceJSONSchema, {
schema: {
resultListLocator: "ResultSet.Result",
resultFields: ["symbol", "name", "exch", "type", "exchDisp"]
}
});
acNode.plug(Y.Plugin.AutoComplete, {
maxResults: 10,
resultTextLocator: "symbol",
resultFormatter: function (query, results) {
return Y.Array.map(results, function (result) {
var asset = result.raw,
text = asset.symbol +
" " + asset.name +
" (" + asset.type +
" - " + asset.exchDisp + ")";
return Y.Highlight.all(text, query);
});
},
requestTemplate: "{query}®ion=US&lang=en-US",
source: oDS
});
acNode.ac.on("select", function (e) {
alert(e.result.raw.name);
stockSymbol = e.result.raw.symbol;
compName = e.result.raw.name;
alert("stockSymbol is "+stockSymbol);
alert("compName is "+compName);
});
});
I have a text field where the text is being entered, then I need to display a few pieces of information based on what was entered:
$(document).ready(function(e) {
//$(".selector").button({icons: {primary: "ui-icon-search"}});
//$(".home").button({icons: {primary: "ui-icon-home"}});
var q = window.location.href.split("?ac-input=");
alert("q is "+q)
if (q && q[1])
$("input").val(q[1]);
alert("what is this?" +q[1]);
runForm();
});
..........
function runForm(){
$("#stock_news").html("");
//var stockSymbol = e.result.raw.symbol;
alert('stockSymbol in runForm is ' +stockSymbol);
alert('compname is runForm is '+compName);
var newsStocks = "http://query.yahooapis.com/v1/public/yql?.......";
$.getJSON(newsStocks, function(data) {
var headlines = data.query.results.a;
newStr = "<h3>Current Headlines</h3>";
newStr += "<ol>";
for(var i=0; i<headlines.length; ++i){
var news = headlines[i];
newStr += "<li><a href='"+news.href+"'>"+news.content+"</a></li>";
}
newStr += "</ol>";
$("#stock_news").html(newStr);
});
htmlStr = '<img src="http://chart.finance.yahoo.com/z?s='+stockSymbol+'&t=5d&q=l&l=off&z=s®ion=US&lang=en-EN"/>';
$("#stock_graph").html(htmlStr);
}
What is happening is, the stockSymbol and compName are correctly set from entering, but for some reason nothing renders on the page, as q is undefined....Any ideas on where I am messing up here?
Figured it out. I needed to call runForm inside the acNode.ac.on("select", function (e)