How to remove dynamically added texbox - forms

I found a good workin example where one can dynamically add textbox and calculate average from those inputs but i can´t figure out how to delete those added textboxes... I know i should do it with first with document.getElementById but what is the id i should look for? And then continue with removechild command?...I´m really newbie, can you please help me?
See here on JSFiddle http://jsfiddle.net/davidThomas/vzftsz3a/1/
JS
function currentlyExisting(selector) {
return document.querySelectorAll(selector).length;
}
function addNew() {
var parent = document.getElementById(this.dataset.divname),
label = document.createElement('label'),
input = document.createElement('input'),
current = currentlyExisting('input[name="myInputs[]"'),
limit = 10;
if (current < limit) {
input.type = 'text';
input.name = 'myInputs[]';
label.appendChild(document.createTextNode('Subject number ' + (current + 1) + ':'));
label.appendChild(input);
parent.appendChild(label);
this.disabled = currentlyExisting('input[name="myInputs[]"') >= limit;
}
}
function average() {
var parent = document.getElementById('dynamicInput'),
inputs = parent.querySelectorAll('input[name="myInputs[]"]'),
sum = Array.prototype.map.call(inputs, function (input) {
return parseFloat(input.value) || 0;
}).reduce(function (a, b) {
return a + b;
}, 0),
average = sum / inputs.length;
document.getElementById('average').textContent = average;
document.getElementById('sum').textContent = sum;
document.getElementById('total').textContent = inputs.length;
}
document.getElementById('addNew').addEventListener('click', addNew);
document.getElementById('btnCompute').addEventListener('click', average);

Try below code
function currentlyExisting(selector) {
return document.querySelectorAll(selector).length;
}
function addNew() {
var parent = document.getElementById(this.dataset.divname),
label = document.createElement('label'),
input = document.createElement('input'),
current = currentlyExisting('input[name="myInputs[]"'),
limit = 10;
if (current < limit) {
input.type = 'text';
input.name = 'myInputs[]';
label.appendChild(document.createTextNode('Subject number ' + (current + 1) +
':'));
label.appendChild(input);
parent.appendChild(label);
this.disabled = currentlyExisting('input[name="myInputs[]"') >= limit;
}
}
function average() {
var parent = document.getElementById('dynamicInput'),
inputs = parent.querySelectorAll('input[name="myInputs[]"]'),
sum = Array.prototype.map.call(inputs, function (input) {
return parseFloat(input.value) || 0;
}).reduce(function (a, b) {
return a + b;
}, 0),
average = sum / inputs.length;
document.getElementById('average').textContent = average;
document.getElementById('sum').textContent = sum;
document.getElementById('total').textContent = inputs.length;
}
function removeRow() {
var parent = document.getElementById(this.dataset.divname);
parent.removeChild(parent.lastChild);
}
document.getElementById('addNew').addEventListener('click', addNew);
document.getElementById('btnCompute').addEventListener('click', average);
document.getElementById('remove').addEventListener('click', removeRow);
Below is the updated HTML
<div id="results"> <span id="average"></span>
<span id="sum"></span>
<span id="total"></span>
</div>
<form method="POST" action="#">
<div id="dynamicInput">
<label>Subject number 1:
<input type="text" name="myInputs[]" />
</label>
<label>Subject number 2:
<input type="text" name="myInputs[]" />
</label>
<label>Subject number 3:
<input type="text" name="myInputs[]" />
</label>
<label>Subject number 4:
<input type="text" name="myInputs[]" />
</label>
<label>Subject number 5:
<input type="text" name="myInputs[]" />
</label>
</div>
<input id="addNew" data-divname="dynamicInput" type="button" value="Add a subject" />
<input id="btnCompute" data-divname="dynamicInput" type="button" name="BtnCompute" value="Compute Average" />
<input id="remove" data-divname="dynamicInput" type="button" value="Remove subject" />
</form>

Related

Text input cell values clears in table when scrolling

I have an input text value box in a table column in each table row. That data is fetched initially and populates in that particular table cell initially. This cell is editable by the user where it can be later saved in the DB upon clicking on a save button.
However the issue occurs when the user input the value in text field and scrolls up and down. The value gets cleared and defaults to the default fetched one. Is there anyway I can prevent that? When the table has small number of records this is not an issue rather the issue occurs when you have a large set of rows.
Does this has any configuration at table level or do I need to implement some soft of eventing mechanism for text inputs?
Here is the code.
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast",
"sap/ui/model/json/JSONModel",
"sap/ui/Device",
"sap/ui/table/Table",
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator",
"sap/ui/ux3/FacetFilter",
"sap/m/TablePersoController",
"sap/m/UploadCollectionParameter",
"sap/m/MessageBox"
], function(Controller, MessageToast, JSONModel, Device, models, Filter, FilterOperator, TablePersoController) {
"use strict";
var dataPath;
var oModel;
var that;
var items;
var jModel = new sap.ui.model.json.JSONModel();
var result = {};
var ppernr;
var from_date;
var to_date;
var oTableEntry;
var t_ttwork = 0;
var t_ttout = 0;
var t_ttoin = 0;
var t_ttShift = 0;
var t_ttmhrs = 0;
var t_tthrapp = 0;
var t_AddHRs = 0;
var t_Syshr = 0;
var t_Penalty = 0;
function roundToTwo(num) {
return +(Math.round(num + "e+2") + "e-2");
}
return Controller.extend("OVERTIME.controller.OTMain", {
onInit: function() {
// dataPath = "/webidedispatcher/destinations/AV_GWD/sap/opu/odata/SAP/ZHRPT_OVERTIME_SRV/";
dataPath = "/sap/opu/odata/SAP/ZHRPT_OVERTIME_SRV/";
oModel = new sap.ui.model.odata.ODataModel(dataPath);
that = this;
that.setDates();
that.GET_DATA();
},
GET_DATA: function(oEvent) {
result.historySet = [];
// var URI = "/EMP_DETAILSSet?$filter=Pernr eq '" + pernr + "'";
oModel.read("/EMP_DETAILSSet/", null, null, false, function(oData, oResponse) {
result.EMP_DETAILSSet = oData.results;
items = result.EMP_DETAILSSet;
result.historySet = oData.results;
jModel.setData(result);
that.getView().setModel(jModel);
});
},
OnPressList: function(oEvent) {
t_ttwork = 0;
t_ttout = 0;
t_ttoin = 0;
t_ttShift = 0;
t_ttmhrs = 0;
t_tthrapp = 0;
t_AddHRs = 0;
t_Syshr = 0;
t_Penalty = 0;
if (items !== "") {
var BindingContext = oEvent.getSource().getBindingContext();
result.EMP_DATASet = BindingContext.getProperty();
jModel.setData(result);
that.getView().setModel(jModel);
ppernr = BindingContext.getProperty("Pernr");
that.getData();
}
},
getData: function() {
if (ppernr !== undefined) {
from_date = that.getView().byId("fdate").getValue();
to_date = that.getView().byId("tdate").getValue();
var oFilter = new Array();
oFilter[0] = new sap.ui.model.Filter("Pernr", sap.ui.model.FilterOperator.EQ, ppernr);
oFilter[1] = new sap.ui.model.Filter("FromDate", sap.ui.model.FilterOperator.EQ, from_date);
oFilter[2] = new sap.ui.model.Filter("ToDate", sap.ui.model.FilterOperator.EQ, to_date);
var oTable = this.getView().byId("oTable");
//this.getView().setModel(oModel);
oTable.setModel(oModel);
oTable.bindRows({
//method: "GET",
path: '/EE_OVETIMESet/',
filters: oFilter
});
// that.OnCalc();
} else {
// MessageToast.show("Please select employee first");
sap.m.MessageBox.show("Please select employee first", {
icon: sap.m.MessageBox.Icon.ERROR,
title: "Error",
onClose: function(evt) {}
});
}
},
OnCalc: function() {
oTableEntry = this.getView().byId("oTable");
var count = oTableEntry._getRowCount();
var oTData;
var cells;
var hour_inoffice = 0;
var minute_inoffice = 0;
var hour_shift = 0;
var minute_shift = 0;
var hour_manual = 0;
var minute_manual = 0;
var hour_sys = 0;
var minute_sys = 0;
var hour_hr = 0;
var minute_hr = 0;
// var second = 0;
t_ttoin = 0;
t_ttShift = 0;
t_ttmhrs = 0;
t_tthrapp = 0;
t_Syshr = 0;
t_AddHRs = 0;
for (var i = 0; i < count; i++) {
oTData = oTableEntry.getContextByIndex(i).getObject();
//cells = oTableEntry.getRows()[i].getCells();
var hrAppValue = oTableEntry.getRows()[i].getCells()[9]._lastValue;
if (oTData.InOffice !== "") {
var splitTime1 = oTData.InOffice.split(':');
hour_inoffice = hour_inoffice + parseInt(splitTime1[0]);
minute_inoffice = minute_inoffice + parseInt(splitTime1[1]);
}
if (oTData.EligableHours !== "") {
var splitTime1 = oTData.EligableHours.split(':');
hour_shift = hour_shift + parseInt(splitTime1[0]);
minute_shift = minute_shift + parseInt(splitTime1[1]);
}
if (oTData.ManualOvt !== "") {
var splitTime1 = oTData.ManualOvt.split(':');
hour_manual = hour_manual + parseInt(splitTime1[0]);
//minute_manual = minute_manual + parseInt(splitTime1[1]);
}
if (oTData.TimeDiff !== "") {
var splitTime1 = oTData.TimeDiff.split(':');
if (splitTime1[0].charAt(0) === "+") {
splitTime1[0] = splitTime1[0].replace('+', '');
hour_sys = hour_sys + parseInt(splitTime1[0]);
minute_sys = minute_sys + parseInt(splitTime1[1]);
} else {
splitTime1[0] = splitTime1[0].replace('-', '');
hour_sys = hour_sys - parseInt(splitTime1[0]);
minute_sys = minute_sys - parseInt(splitTime1[1]);
}
}
if (hrAppValue !== "") {
var splitTime1 = hrAppValue.split(':');
if (splitTime1[0].charAt(0) === "+") {
splitTime1[0] = splitTime1[0].replace('+', '');
hour_hr = hour_hr + parseInt(splitTime1[0]);
minute_hr = minute_hr + parseInt(splitTime1[1]);
} else {
splitTime1[0] = splitTime1[0].replace('-', '');
hour_hr = hour_hr - parseInt(splitTime1[0]);
minute_hr = minute_hr - parseInt(splitTime1[1]);
}
}
/* minute_inoffice = minute_inoffice%60;
second_inoffice = parseInt(splitTime1[2]);
minute_inoffice = minute_inoffice + second_inoffice/60;
second_inoffice = second_inoffice%60;*/
/* if (parseFloat(cells[3].getText()) > 0) {
t_ttwork = parseFloat(t_ttwork) + parseFloat(cells[3].getText().replace(':', '.'));
}
t_ttout = parseFloat(t_ttout) + parseFloat(cells[4].getText().replace(':', '.'));
t_ttoin = parseFloat(t_ttoin) + parseFloat(cells[5].getText().replace(':', '.'));
t_ttShift = parseFloat(t_ttShift) + parseFloat(cells[6].getText()); //.replace(':', '.'));
t_ttmhrs = parseFloat(t_ttmhrs) + parseFloat(cells[7].getText().replace(':', '.'));
t_tthrapp = parseFloat(t_tthrapp) + parseFloat(cells[9].getValue().replace(':', '.'));
if (parseFloat(cells[9].getValue().replace(':', '.')) > 0) {
t_AddHRs = parseFloat(t_AddHRs) + parseFloat(cells[9].getValue());
} else if (parseFloat(cells[9].getValue().replace(':', '.')) < 0) {
t_Penalty = parseFloat(t_Penalty) + parseFloat(cells[9].getValue());
}*/
}
var temp;
t_ttoin = roundToTwo(hour_inoffice + minute_inoffice / 60);
t_ttShift = roundToTwo(hour_shift + minute_shift / 60);
t_ttmhrs = hour_manual;
t_Syshr = roundToTwo(hour_sys + minute_sys / 60);
t_AddHRs = roundToTwo(hour_hr + minute_hr / 60);
/* temp = t_ttoin ;
temp = '.' + temp.split('.') ;
temp[1] = temp[1] * 60 ;
t_ttoin = temp[0] + ':' + temp[1] ;*/
// this.getView().byId("t_ttwork").setValue(t_ttwork);
// this.getView().byId("t_ttoout").setValue(t_ttout);
this.getView().byId("t_ttoin").setValue(t_ttoin);
this.getView().byId("t_ttShift").setValue(t_ttShift);
this.getView().byId("t_ttmhrs").setValue(t_ttmhrs);
this.getView().byId("t_tsyshr").setValue(t_Syshr);
this.getView().byId("t_tthrapp").setValue(t_AddHRs);
// this.getView().byId("t_Penalty").setValue(t_Penalty);
},
setDates: function() {
var today = new Date();
var dd = today.getDate().toString();
var mm = (today.getMonth() + 1).toString(); //January is 0!
var yyyy = today.getFullYear();
var date = yyyy.toString().concat((mm[1] ? mm : "0" + mm[0]).toString(), '01');
this.getView().byId("fdate").setValue(date);
var lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 15);
lastDay = yyyy.toString().concat((mm[1] ? mm : "0" + mm[0]).toString(), lastDay.getDate());
this.getView().byId("tdate").setValue(lastDay);
},
OngetData: function(oEvent) {
that.getData();
},
OnSave: function(oEvent) {
var oTEntry = this.getView().byId("oTable");
var count = oTEntry._getRowCount();
var cells;
var bodyArray = [];
for (var i = 0; i < count; i++) {
var oTData = oTEntry.getContextByIndex(i).getObject();
//cells = oTableEntry.getRows()[i].getCells();
var hrAppValue = oTableEntry.getRows()[i].getCells()[9]._lastValue;
var requestBody = {};
requestBody.Pernr = "" + oTData.Pernr;
requestBody.FromDate = "" + oTData.FromDate;
requestBody.ToDate = "" + oTData.ToDate;
requestBody.OtDate = "" + oTData.OtDate;
requestBody.FcIn = "" + oTData.FcIn;
requestBody.LcOut = "" + oTData.LcOut;
requestBody.LogicHours = "" + oTData.LogicHours;
requestBody.OutOffice = "" + oTData.OutOffice;
requestBody.InOffice = "" + oTData.InOffice;
requestBody.EligableHours = "" + oTData.EligableHours;
requestBody.ManualOvt = "" + oTData.ManualOvt;
requestBody.HrApp = "" + hrAppValue; //oTData.HrApp;
bodyArray.push(requestBody);
}
var Sflag;
for (var i = 0; i < bodyArray.length; i++) {
oModel.create("/EE_OVETIMESet", bodyArray[i], {
success: function(oData, oResponse) {
Sflag = "S";
},
error: function() {
Sflag = "E";
break;
}
});
}
/**oModel.create("/EE_OVETIMESet", bodyArray, {
success: function(oData, oResponse) {
Sflag = "S";
},
error: function() {
Sflag = "E";
}
});*/
if (Sflag === "S") {
var msg = "Saved Successfully";
sap.m.MessageBox.show(msg, {
icon: sap.m.MessageBox.Icon.SUCCESS,
title: "Success",
onClose: function(evt) {}
});
} else {
sap.m.MessageBox.show("Data Not Saved", {
icon: sap.m.MessageBox.Icon.ERROR,
title: "Error",
onClose: function(evt) {}
});
}
},
OnApprove: function(oEvent) {
var requestBody = {};
requestBody.Pernr = ppernr;
requestBody.FromDate = from_date;
requestBody.ToDate = to_date;
requestBody.Svalue = this.getView().byId("t_AddHRs").getValue();
requestBody.Pvalue = this.getView().byId("t_Penalty").getValue();
/* if (this.getView().byId("addover").getSelected() === true ) {
requestBody.Sflag = "A";
requestBody.Svalue = this.getView().byId("t_AddHRs").getValue();
} else if (this.getView().byId("subover").getSelected() === true ) {
requestBody.Sflag = "P";
requestBody.Pvalue = this.getView().byId("t_Penalty").getValue();
}*/
oModel.create("/EE_SOVTSet", requestBody, {
// method: "POST",
success: function(oData, oResponse) {
var status = oData.STATUS;
if (status === "S") {
sap.m.MessageBox.show("Data Saved", {
icon: sap.m.MessageBox.Icon.SUCCESS,
title: "Success",
onClose: function(evt) {}
});
} else if (status === "E") {
sap.m.MessageBox.show("Data Not Saved", {
icon: sap.m.MessageBox.Icon.ERROR,
title: "Error",
onClose: function(evt) {}
});
}
},
error: function() {
MessageToast.show("Error. Try Again");
}
});
},
onNavBack: function() {
window.history.go(-1);
},
onSearch: function(oEvt) {
var sQuery = oEvt.getSource().getValue();
if (sQuery && sQuery.length > 0) {
var filter1 = new sap.ui.model.Filter("Pernr", sap.ui.model.FilterOperator.Contains, sQuery);
var filter2 = new sap.ui.model.Filter("Name", sap.ui.model.FilterOperator.Contains, sQuery);
var allfilter = new sap.ui.model.Filter([filter1, filter2], false);
}
var list = this.getView().byId("idList");
var binding = list.getBinding("items");
binding.filter(allfilter);
}
});
});
View
<mvc:View controllerName="OVERTIME.controller.OTMain" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
xmlns:f="sap.ui.layout.form" xmlns:t="sap.ui.table" xmlns:co="sap.ui.commons" xmlns:sc="sap.ui.core">
<SplitApp id="idSplitApp">
<masterPages>
<Page id="idMaster" title="{i18n>title}" icon="sap-icon://action" class="sapUiSizeCompact">
<headerContent class="sapUiSizeCompact"></headerContent>
<subHeader>
<Toolbar>
<SearchField width="100%" liveChange="onSearch" class="sapUiSizeCompact"/>
</Toolbar>
</subHeader>
<content>
<List id="idList" items="{/EMP_DETAILSSet}" class="sapUiSizeCompact">
<items class="Masterpage">
<ObjectListItem title="{Name}" type="Active" press="OnPressList" class="Masterpage">
<firstStatus>
<!--<ObjectStatus text="{Pernr}"/>-->
</firstStatus>
<attributes>
<ObjectAttribute text="{Pernr}"/>
</attributes>
</ObjectListItem>
</items>
</List>
</content>
<footer>
<Toolbar>
<ToolbarSpacer/>
</Toolbar>
</footer>
</Page>
</masterPages>
<detailPages>
<Page id="idDetails" showHeader="true" title="{i18n>appTitle}" class="sapUiSizeCompact" showNavButton="true" navButtonText="Back"
navButtonPress="onNavBack">
<ObjectHeader id="oh1" responsive="true" binding="{/EMP_DATASet}" intro="{i18n>pernr} - {Pernr}" title="{i18n>name} - {Name}"
showMarkers="false" markFlagged="false" markFavorite="false" backgroundDesign="Translucent">
<attributes>
<ObjectAttribute title="{i18n>org}" text="{Orgtx}"/>
<ObjectAttribute title="{i18n>posi}" text="{Postx}"/>
<ObjectAttribute title="{i18n>group}" text="{Ptext01}"/>
</attributes>
<statuses>
<ObjectStatus title="{i18n>subgroup}" text="{Ptext02}"/>
<ObjectStatus title="" text=""/>
</statuses>
</ObjectHeader>
<IconTabBar id="idIconTabBarMulti" class="sapUiResponsiveContentPadding">
<items>
<IconTabFilter icon="sap-icon://account">
<f:SimpleForm xmlns:sap.ui.layout.form="sap.ui.layout.form" xmlns:sap.ui.core="sap.ui.core" editable="fales" layout="ResponsiveGridLayout"
id="from_header" title="">
<f:content>
<Label text="{i18n>fromdate}" id="l_fdate" required="true"/>
<DatePicker width="30%" id="fdate" valueFormat="yyyyMMdd" displayFormat="dd/MM/yyyy"/>
<Label text="{i18n>todate}" id="l_tdate" required="true"/>
<DatePicker width="61%" id="tdate" valueFormat="yyyyMMdd" displayFormat="dd/MM/yyyy"/>
<Button id="iddate" press="OngetData" type="Unstyled" icon="sap-icon://display" width="30%"/>
</f:content>
</f:SimpleForm>
<f:SimpleForm xmlns:sap.ui.layout.form="sap.ui.layout.form" xmlns:sap.ui.core="sap.ui.core" editable="fales" layout="ResponsiveGridLayout"
id="from_overtime" title="">
<f:content id="cc">
<ScrollContainer horizontal="true" vertical="false" focusable="true" width="55rem">
<!--<sc:ScrollBarheight="20rem" vertical="false" size = "200px" contentSize = "500px" scrollPosition = "50"> -->
<t:Table selectionMode="None" id="oTable" navigationMode="Paginator" filter="onfilter" showNoData="true" width="70rem" visibleRowCount="16">
<t:columns>
<t:Column id="c_odate" width="10%" autoResizable="true">
<Label text="{i18n>odate}"/>
<t:template>
<Label id="t_odate" text="{OtDate}"/>
</t:template>
</t:Column>
<t:Column id="c_cin" autoResizable="true">
<Label text="{i18n>cin}"/>
<t:template>
<Label id="t_cin" text="{FcIn}"/>
</t:template>
</t:Column>
<t:Column id="c_cout" autoResizable="true">
<Label text="{i18n>cout}"/>
<t:template>
<Label id="t_cout" text="{LcOut}"/>
</t:template>
</t:Column>
<t:Column id="c_lhour" autoResizable="true">
<Label text="{i18n>lhour}"/>
<t:template>
<Label id="t_lhour" text="{LogicHours}"/>
</t:template>
</t:Column>
<t:Column id="c_toout" autoResizable="true">
<Label text="{i18n>toout}"/>
<t:template>
<Label id="t_toout" text="{OutOffice}"/>
</t:template>
</t:Column>
<t:Column id="c_toin" autoResizable="true">
<Label text="{i18n>toin}"/>
<t:template>
<Label id="t_toin" text="{InOffice}"/>
</t:template>
</t:Column>
<t:Column id="c_elhours" autoResizable="true">
<Label text="{i18n>elhours}"/>
<t:template>
<Label id="t_elhours" text="{EligableHours}"/>
</t:template>
</t:Column>
<!-- <t:Column id="c_stime" autoResizable="true">
<Label text="{i18n>stime}"/>
<t:template>
<Label id="t_stime" text="{TimeDiff}"/>
</t:template>
</t:Column>-->
<t:Column id="c_mover" autoResizable="true">
<Label text="{i18n>mover}"/>
<t:template>
<Label id="t_mover" text="{ManualOvt}"/>
</t:template>
</t:Column>
<t:Column id="c_diff" autoResizable="true">
<Label text="{i18n>tdiff}"/>
<t:template>
<Label id="t_diff" text="{TimeDiff}"/>
</t:template>
</t:Column>
<t:Column id="c_hrapp" autoResizable="true">
<Label text="{i18n>hrapp}"/>
<t:template>
<Input id="t_hrapp" value="{HrApp}"/>
</t:template>
</t:Column>
<!-- <t:Column id="c_ElgHrApp" autoResizable="true">
<Label text="{i18n>ElgHrApp}"/>
<t:template>
<Label id="t_ElgHrApp" text="{ElgHrApp}"/>
</t:template>
</t:Column>-->
</t:columns>
</t:Table>
</ScrollContainer>
<!-- </sc:ScrollBar>-->
</f:content>
</f:SimpleForm>
<f:SimpleForm xmlns:sap.ui.layout.form="sap.ui.layout.form" xmlns:sap.ui.core="sap.ui.core" editable="true" layout="ResponsiveGridLayout"
id="from_tovertime" title="Totals ">
<Button id="idCalc" text="{i18n>Calc}" press="OnCalc" type="Default" icon="sap-icon://simulate" width="10%"/>
<f:content id="cc1">
<!-- <Label id="t_twork" text="{i18n>TWOffice}"/>
<Input id="t_ttwork" editable="false" width="40%"/>
<Input id="t_ttout" value="{i18n>TOutOffice}" editable="false"/>
<Input id="t_ttoout" type="Number" editable="false"/>-->
<Label id="t_ttin" text="{i18n>TInOffice}"/>
<Input id="t_ttoin" type="Number" editable="false"/>
<Input id="t_tShift" value="{i18n>TShift}" editable="false"/>
<Input id="t_ttShift" type="Number" editable="false"/>
<Label id="t_tmhrs" text="{i18n>Tmhrs}"/>
<Input id="t_ttmhrs" type="Number" editable="false"/>
<Label id="t_syshr" text="{i18n>Tsyshr}"/>
<Input id="t_tsyshr" editable="false" width="40%"/>
<Input id="t_thrapp" value="{i18n>thrapp}" editable="false"/>
<Input id="t_tthrapp" type="Number" editable="false"/>
</f:content>
</f:SimpleForm>
<f:SimpleForm xmlns:sap.ui.layout.form="sap.ui.layout.form" xmlns:sap.ui.core="sap.ui.core" editable="false" layout="ResponsiveLayout"
id="from_tovertime2" title="Approved Hrs ">
<f:content >
<!--<RadioButton id="addover" groupName="G1" text="Add Over Hrs" selected="true" valueState="Warning"/>-->
<Label id="l_AddHRs" text="Add Over Hrs"/>
<Input id="t_AddHRs" type="Number" editable="true" width="30%" valueState="Success"/>
<!--<RadioButton id="subover" groupName="G1" text="Add Penalty" valueState="Error"></RadioButton>-->
<Label id="l_Penalty" text="Add Penalty"/>
<Input id="t_Penalty" type="Number" editable="true" width="30%"/>
</f:content>
</f:SimpleForm>
</IconTabFilter>
<!--<IconTabFilter icon="sap-icon://attachment">
<Panel>
<UploadCollection id="UploadCollection" maximumFilenameLength="55" multiple="true" showSeparators="None" items="{/AttachmentsSet}"
change="onChange" fileDeleted="onFileDeleted" uploadComplete="onUploadComplete">
<UploadCollectionItem fileName="{Filename}" mimeType="{MimeType}" url="{url}"/>
</UploadCollection>
</Panel>
</IconTabFilter>-->
</items>
</IconTabBar>
<footer>
<Toolbar>
<ToolbarSpacer/>
<Button id="idSubmit" text="{i18n>save}" press="OnSave" type="Emphasized" icon="sap-icon://add"/>
<Button id="idApprove" text="{i18n>approve}" press="OnApprove" type="Accept" icon="sap-icon://accept"/>
<Button id="idCancel" text="{i18n>close}" press="onNavBack" type="Reject" icon="sap-icon://sys-cancel"/>
</Toolbar>
</footer>
</Page>
</detailPages>
</SplitApp>
</mvc:View>
From the SDK documentation
In order to keep the document DOM as lean as possible, the Table control reuses its DOM elements of the rows. When the user scrolls, only the row contexts are changed but the rendered controls remain the same. This allows the Table control to handle huge amounts of data. Nevertheless, restrictions apply regarding the number of displayed columns. Keep the number as low as possible to improve performance. Due to the nature of tables, the used control for column templates also has a big influence on the performance.
Emphasis mine. I think the behavior you're describing is as designed.
How much data are you displaying this way? If you don't need to display thousands of lines, you might be better of going with sap.m.Table which does not do this.
The issue is because of the ODataModel. Used the version 2 of ODataModel which solved the issue.
ODataModel v2 API Documentation

Google Apps Script - do not send email for checkbox is unchecked

I have the following HTML file written in the script editor within google sheets:
<body>
<form>
<div class="even group">
<input type="text" id="yourName" class="contactNameInput" name="yourName" placeholder="Your name">
<input type="text" id="yourPosition" class="contactNameInput" name="yourPosition" placeholder="Your position">
</div>
<div class="odd group">
<input type="checkbox" id="check1" class="check" checked>
<input type="text" id="name1" class="contactNameInput" name="toAddress1">
<input type="text" id="contactName1" class="contactNameInput mailName" name="contactName1">
<input type="text" id="time1" class="contactNameInput hidden mailTime" name="time1">
<input type="text" id="day1" class="contactNameInput hidden mailDay" name="day1">
<input type="text" id="date1" class="contactNameInput hidden mailDate" name="date1">
<textarea class="additional contactNameInput" id="additional1" name="additional1" placeholder="Additional requests..."></textarea>
<div class="preview1"></div>
</div>
<div class="even group">
<input type="checkbox" id="check2" class="check" checked>
<input type="text" name="toAddress2" id="name2" class="contactNameInput">
<input type="text" id="contactName2" class="contactNameInput mailName" name="contactName2">
<input type="text" id="time2" class="contactNameInput hidden mailTime" name="time2">
<input type="text" id="day2" class="contactNameInput hidden mailDay" name="day2">
<input type="text" id="date2" class="contactNameInput hidden mailDate" name="date2">
<textarea class="additional contactNameInput" id="additional2" name="additional2" placeholder="Additional requests..."></textarea>
<div class="preview1"></div>
</div>
// ... there are 33 of these objects in total - all identical except for the ascending Ids...
<div class="odd group">
<input type="checkbox" id="check33" class="check" checked>
<input type="text" name="toAddress33" id="name33" class="contactNameInput">
<input type="text" id="contactName33" class="contactNameInput mailName" name="contactName33">
<input type="text" id="time33" class="contactNameInput hidden mailTime" name="time33">
<input type="text" id="day33" class="contactNameInput hidden mailDay" name="day33">
<input type="text" id="date33" class="contactNameInput hidden mailDate" name="date33">
<textarea class="additional contactNameInput" id="additional33" name="additional33" placeholder="Additional requests..."></textarea>
<div class="preview1"></div>
</div>
<button type="submit" class="btn btn-primary googleGreen" id="load" data-loading-text="<i class='fa fa-spinner fa-spin'></i> Sending">Invite hotels</button>
</form>
<script>
$(".additional").focus(function(){
$('.dearName').html(function() {
return $(this)
.closest('.preview1')
.siblings('.mailName')
.val();
});
$('.meetingDay').html(function() {
return $(this)
.closest('.preview1')
.siblings('.mailDay')
.val();
});
$('.meetingTime').html(function() {
return $(this)
.closest('.preview1')
.siblings('.mailTime')
.val();
});
$('.meetingDate').html(function() {
return $(this)
.closest('.preview1')
.siblings('.mailDate')
.val();
});
$(this).siblings('div:first').slideDown();
}).blur(function() {
$(this).siblings('div:first').slideUp();
});
$(".additional").keyup(function() {
$(this).next('div').find('.addedText').html($(this).val());
});
$(".preview1").html("<p> Dear <span class='dearName'></span></p> <br> <p>Please can we meet on <span class='meetingDay'></span> <span class='meetingDate'></span> at <span class='meetingTime'></span>.</p><br><p><span class='addedText'></span>If you could kindly let me know if you are able to confirm that would be great.</p><br><p>Many thanks and I look forward to hearing from you soon.</p><br><p>Yours sincerely,</p>");
// $(".dearName").html($(".dearName").prev('.preview1').siblings().find('.mailName')val());
var idArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33];
var hotelName = "";
var hotelAddress = "";
var hotelContact = "";
var hotelTel = "";
var hotelEmail = "";
function onSuccess(test){
// var hotelArray = test;
for(var i=0; i<idArray.length; i++){
hotelName = test[i].name;
hotelAddress = test[i].address;
hotelContact = test[i].contact;
hotelTel = test[i].tel;
hotelEmail = test[i].email;
time = test[i].time;
day = test[i].day;
date = test[i].date;
$("#name" + idArray[i]).val(hotelEmail);
$("#contactName" + idArray[i]).val(hotelContact);
$("#time" + idArray[i]).val(time);
$("#day" + idArray[i]).val(day);
$("#date" + idArray[i]).val(date);
}
} google.script.run.withSuccessHandler(onSuccess).findHotel();
window.onload = function() {
document.getElementsByTagName('form')[0]
.addEventListener('submit', function(e) {
e.preventDefault();
google.script.run
.withSuccessHandler(function(result) {
google.script.host.close()
})
.withFailureHandler(function(result) {
console.log("f %s", result)
})
//.withFailureHandler(function(result){toastr.error('Process failed', result)})
.sendEmail(e.currentTarget);
})};
$('.btn').on('click', function() {
var $this = $(this);
$this.button('loading');
setTimeout(function() {
$this.button('reset');
}, 15000);
});
$(".check").click(function(){
$(this).parent().toggleClass("checkDisabled");
$(this).siblings().toggleClass("disabledInput");
if($(this).siblings().hasClass("disabledInput")) {
$(this).siblings().attr("disabled", true);
} else {
$(this).siblings().attr("disabled", false);
}})
$(this).siblings().attr("disabled", true);
$('.dearName').html(function() {
return $(this)
.closest('.preview1')
.siblings('.mailName')
.val();
});
</script>
</body>
Each of the class 'group' divs within the form represents one client and I have a .gs file which then sends an email on submit to all clients so long as there is an email address in the relevant field:
function sendEmail(form) {
const sSheet = SpreadsheetApp.getActiveSpreadsheet();
const file = DriveApp.getFileById(sSheet.getId());
const documentUrl = file.getUrl();
/* var toEmail = form.toAddress;
var ccEmail = form.ccAddress;
var fromEmail = "****#****.com";
var subject = form.subject;
var message = form.message; */
var toEmail = "";
var fromEmail = "****#****.com";
var message = "";
var hotelAddresses = [
form.toAddress1,
form.toAddress2,
form.toAddress3,
form.toAddress4,
form.toAddress5,
form.toAddress6,
form.toAddress7,
form.toAddress8,
form.toAddress9,
form.toAddress10,
form.toAddress11,
form.toAddress12,
form.toAddress13,
form.toAddress14,
form.toAddress15,
form.toAddress16,
form.toAddress17,
form.toAddress18,
form.toAddress19,
form.toAddress20,
form.toAddress21,
form.toAddress22,
form.toAddress23,
form.toAddress24,
form.toAddress25,
form.toAddress26,
form.toAddress27,
form.toAddress28,
form.toAddress29,
form.toAddress30,
form.toAddress31,
form.toAddress32,
form.toAddress33,
];
var contactNames = [
form.contactName1,
form.contactName2,
form.contactName3,
form.contactName4,
form.contactName5,
form.contactName6,
form.contactName7,
form.contactName8,
form.contactName9,
form.contactName10,
form.contactName11,
form.contactName12,
form.contactName13,
form.contactName14,
form.contactName15,
form.contactName16,
form.contactName17,
form.contactName18,
form.contactName19,
form.contactName20,
form.contactName21,
form.contactName22,
form.contactName23,
form.contactName24,
form.contactName25,
form.contactName26,
form.contactName27,
form.contactName28,
form.contactName29,
form.contactName30,
form.contactName31,
form.contactName32,
form.contactName33,
];
var days = [
form.day1,
form.day2,
form.day3,
form.day4,
form.day5,
form.day6,
form.day7,
form.day8,
form.day9,
form.day10,
form.day11,
form.day12,
form.day13,
form.day14,
form.day15,
form.day16,
form.day17,
form.day18,
form.day19,
form.day20,
form.day21,
form.day22,
form.day23,
form.day24,
form.day25,
form.day26,
form.day27,
form.day28,
form.day29,
form.day30,
form.day31,
form.day32,
form.day33,
];
var dates = [
form.date1,
form.date2,
form.date3,
form.date4,
form.date5,
form.date6,
form.date7,
form.date8,
form.date9,
form.date10,
form.date11,
form.date12,
form.date13,
form.date14,
form.date15,
form.date16,
form.date17,
form.date18,
form.date19,
form.date20,
form.date21,
form.date22,
form.date23,
form.date24,
form.date25,
form.date26,
form.date27,
form.date28,
form.date29,
form.date30,
form.date31,
form.date32,
form.date33,
];
var times = [
form.time1,
form.time2,
form.time3,
form.time4,
form.time5,
form.time6,
form.time7,
form.time8,
form.time9,
form.time10,
form.time11,
form.time12,
form.time13,
form.time14,
form.time15,
form.time16,
form.time17,
form.time18,
form.time19,
form.time20,
form.time21,
form.time22,
form.time23,
form.time24,
form.time25,
form.time26,
form.time27,
form.time28,
form.time29,
form.time30,
form.time31,
form.time32,
form.time33,
];
var additionalInfo = [
form.additional1,
form.additional2,
form.additional3,
form.additional4,
form.additional5,
form.additional6,
form.additional7,
form.additional8,
form.additional9,
form.additional10,
form.additional11,
form.additional12,
form.additional3,
form.additional14,
form.additional15,
form.additional16,
form.additional17,
form.additional18,
form.additional19,
form.additional20,
form.additional21,
form.additional22,
form.additional23,
form.additional24,
form.additional25,
form.additional26,
form.additional27,
form.additional28,
form.additional29,
form.additional30,
form.additional31,
form.additional32,
form.additional33,
];
for(var i = 0; i<times.length; i++){
var subject = "Meeting - " + days[i] + ", " + dates[i] + " at " + times[i];
toEmail = hotelAddresses[i];
message = "Dear " + contactNames[i] + ","
+"<br><br>"+
"Please can we meet on " + days[i] + " " + dates[i] + " at " + times[i] + "." + "<br>" + "<br>" +
additionalInfo[i] +
" If you could kindly let me know if you are able to confirm that would be great." + "<br>" + "<br>" +
"Many thanks and I look forward to hearing from you soon." + "<br>" + "<br>" +
"Yours sincerely," + "<br>" + "<br>" +
form.yourName + "<br>" + "<br>"
+ "<em><b>" + form.yourPosition + "</b></em> <br><br>" +
"<span style='color:#0e216d'><b> Company name </b>" + "<br>" +
"Company address</span><br>" +
"<img src='companylogo.jpg' style='width: 50%; margin-top: 10px'>";
if(toEmail) {
GmailApp.sendEmail(
toEmail, // recipient
subject, // subject
'test', { // body
htmlBody: message // advanced options
}
);
}}
}
However, as well as not sending an email when there is no address entered, I need to stop the email from sending when the checkbox is not checked. I'm not quite sure where to start with this...
A bit of restructuring of your code is probably going to help you a lot here. For example, the hotelAddresses array is currently a manually created list of addresses - hard to maintain. I'd begin by using the group class on all of the divs to your advantage, as you can select every single one, in order, using the document.getElementsByClassName("group") selector. This will return an array of all your group elements.
Now that we have an array of all these groups, we can process them in a much more concise way. For example, creating that hotel addresses array becomes as simple as:
var hotelAddresses = [], groupElements = document.getElementsByClassName("group")
for (var i = 1; i < groupElements.length; i++) {
var isChecked = groupElements[i].getElementsByClassName("check")[0].checked
var address = groupElements[i].getElementsByClassName("contactNameInput")[0].value
if (isChecked && address != "") { // Add if is checked and has an address
hotelAddresses.push(address)
}
}
You can easily add the code for the contactNames and other arrays in to this same loop. Maybe even another data structure which is an array of your groups for much easier access.
var groups = []
... // Loop code
groups.push({
address: groupElements[i].getElementsByClassName("contactNameInput")[0].value,
contactName: ...
})
You get the idea! Hope this helps you out a bit.

Find location of line on Canvas drawing

Thanks for the previous answer.
I have added a some more drawings to the canvas.I have also times(*) everything by 3 so I can see the lines better.
There is a straight line from the top to the bottom.
Is there a way to figure out where "var hdr" would hit that line?
h1 needs to be calculated for when hdr+h2 hits the line.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var p1=7.5*3;
var p2=10.25*3;
var lp=16
var max = lp; // how many times
ctx.moveTo(0,0);
for(i=1; i <= max; i++){
ctx.lineTo(p2*(i-1),p1 * i);
ctx.lineTo(p2 * i,p1 * i);
}
ctx.lineTo(p2*lp,p1*lp);
ctx.lineTo(0,0);
ctx.stroke();
var htx = c.getContext("2d");
var h1=100*3//h1 needs to be calculated
var h2=12*3
var h3=3*3
var hdr=80*3
htx.rect(h1,0,h3,h2);
htx.stroke();
ctx.lineTo(h1,h2);
ctx.lineTo(h1,hdr);
ctx.stroke();
</script>
</body>
</html>
This code has progressed quite well, how do I scale this so it always fits in the canvas?
<!DOCTYPE html>
<html>
<body>
<label for="text1">LP:
<input type="text" size="5" maxlength="5" name="text1" value="16" id="lp" />
</label>
<label for="text2">p1:
<input type="text" size="5" maxlength="5" name="text2" value="7.50" id="p1" />
</label>
<label for="text3">p2:
<input type="text" size="5" maxlength="5" name="text2" value="10.0" id="p2" />
</label>
<label for="text4">h2:
<input type="text" size="5" maxlength="5" name="text4" value="12" id="h2" />
</label>
<label for="text5">hdr:
<input type="text" size="5" maxlength="5" name="text5" value="80" id="hdr" />
</label>
<input type="button" value="Calculate" onclick="calc()">
<br>
<br>
<br>
<br>
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">
<br />Your browser does not support the HTML5 canvas tag.</canvas>
<script type="text/javascript">
function calc() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var p1 = parseFloat(document.getElementById("p1").value);
var p2 = parseInt(document.getElementById("p2").value);
var lp = parseInt(document.getElementById("lp").value);
var max = lp; // how many times
ctx.moveTo(0, 0);
for (i = 1; i <= max; i++) {
ctx.lineTo(p2 * (i - 1), p1 * i);
ctx.lineTo(p2 * i, p1 * i);
}
ctx.lineTo(p2 * lp, p1 * lp);
ctx.lineTo(0, 0);
ctx.stroke();
var htx = c.getContext("2d");
var h2 = parseInt(document.getElementById("h2").value);
var h3 = 3
var hdr = parseInt(document.getElementById("hdr").value);
var h1 = ((h2 + hdr) / p1 * p2) //h1 needs to be calculated
htx.rect(h1, 0, h3, h2);
htx.stroke();
ctx.lineTo(h1, h2);
ctx.lineTo(h1, hdr + h2);
ctx.stroke();
alert(h1)
}
</script>
</body>
</html>
thanks

Form redirect based on radio buttons and tick boxes?

How do i create a form that will redirect the user to a different URL based on what they select?
The form will be very similar to https://www.dropbox.com/upgrade where you have 3 main radio buttons, monthly or annual radio buttons and a tick box for an add-on.
The form would also calculate the selections.
Without seeing any code, the simplest way you can do this is by using an onclick event for the radio buttons which would update the form action property. A crude example would be:
<html>
<head></head>
<body>
<form onsubmit="submitForm();" id="myForm" type="get">
<input type="radio" name="myRadio1" data-op="0" value="10" onclick="calcNow();" selected />Monthly
<input type="radio" name="myRadio1" data-op="1" value="120" onclick="calcNow();" />Annually<br/>
<input type="radio" name="myRadio2" data-op="0" value="10" onclick="calcNow();" selected />Option A
<input type="radio" name="myRadio2" data-op="1" value="20" onclick="calcNow();" />Option B<br/>
<input id="myCheckbox" name="myCheckbox" type="checkbox" value="10" onclick="calcNow();" />Add-on<br/>
<input id="myTotal" name="myTotal" type="text" value="" disabled="disabled" /><br/>
<input type="button" id="myButton" onclick="submitForm();" value="Continue" />
</form>
<script type="text/javascript">
var pages = [[["page1.html","page2.html"],["page3.html","page4.html"]],[["page5.html","page6.html"],["page7.html","page8.html"]]];
function calcNow()
{
var cb = document.getElementById("myCheckbox");
var cost1 = getRadioValue("myRadio1");
var cost2 = getRadioValue("myRadio2");
var cost3 = cb.checked ? parseInt(cb.value) : 0;
var costTotal = cost1 + cost2 + cost3;
document.getElementById("myTotal").value = costTotal;
var op1 = getRadioData("myRadio1", "op");
var op2 = getRadioData("myRadio2", "op");
var op3 = cb.checked ? 1 : 0;
if (op1 != undefined && op2 != undefined && op3 != undefined)
{
return pages[op1][op2][op3];
}
return undefined;
}
function submitForm()
{
var page = calcNow();
if (page != undefined)
{
// ---- To popup ----
//alert(page);
// ---- To navigate ----
location.href = page;
// ---- To alter post ----
//var form = document.getElementById("myForm");
//form.action = page;
//form.submit();
}
else
{
alert("Please answer all questions.");
}
}
function getRadioValue(name)
{
var controls = document.getElementsByName(name);
for (var i = 0; i < controls.length; i++) {
if (controls[i].checked) {
return parseInt(controls[i].value);
}
}
return 0;
}
function getRadioData(name, attribute)
{
var controls = document.getElementsByName(name);
for (var i = 0; i < controls.length; i++) {
if (controls[i].checked) {
return parseInt(controls[i].dataset[attribute]);
}
}
return undefined;
}
</script>
</body>
</html>
Note that this is quite basic html and javascript, so if you are having troubles with this you may need to get in touch with a web designer. This part is the easy bit!

Add a unique ID to form input for total

The problem I'm having is i'm working on an invoicing system. Which uses this,
$(document).ready(function() {
$('#add').click(function() {
JQuery('#lineItems').append('<input type="text" name="description[]"
class="ui-corner-all text invDesc" />
<input type="text" name="qty[]" class="ui-corner-all text invQty" />
<input type="text" name="amount[]" class="ui-corner-all text invAmount"
title="Amount" />
<input type="hidden" name="rowTotal[]" class="row-total-input" />');
});
});
to create new line item. The hidden input named rowTotal[] is meant to hold the totals of each row so they can be added up. The Code i am using to get the row total of qty * amount is,
$(function(){
$('.row-total-input').each(
function( intIndex ){
$('.invAmount').livequery('blur', function() {
var $this = $(this);
var amount = $this.val();
var qty = $this.parent().find('.invQty').val();
if ( (IsNumeric(amount)) && (amount != '') ) {
var rowTotal = qty * amount;
$this.css("background-color", "white").parent().find(".row-total-input").val(rowTotal);
} else {
$this.css("background-color", "#ffdcdc");
};
calcProdSubTotal();
calcOrderTotal();
});
}
);
});
However it updates all the rowTotal[] input fields to the last row total so the final sum isn't correct.
I am assuming I need to create some sort of unique ID for each rowTotal[] so only the correct one is updated. I just don't know how to do it.
Thanks in advance.
Ah the problem is here:
var qty = $this.parent().find('.invQty').val();
If each row would have a distinct parent it would be fine, but all the 'rows' are contained within the same parent - #lineItems. What should help is changing your current row creation code to this:
$(document).ready(function() {
$('#add').click(function() {
JQuery('#lineItems').append('<div><input type="text" name="description[]"
class="ui-corner-all text invDesc" />
<input type="text" name="qty[]" class="ui-corner-all text invQty" />
<input type="text" name="amount[]" class="ui-corner-all text invAmount"
title="Amount" />
<input type="hidden" name="rowTotal[]" class="row-total-input" /></div>');
//notice the extra div tag that wrapps around all the input fields
});
});