Calculate a total from autocomplete suggestion.data - html

I'm trying to write a small Jquery program with an autocomplete searchform. I would like the user to be able to add items from the autocomplete form to a sort of shopping list. I have difficulties finding a way to calculate and update the total price of all added products, I tried to store the prices, which are in suggestion.data and tot add it recusively to a total as in
total = total + suggestion.data, but this seems not to be the way. Could someone help me to produce and display this total? My jQuery code is as follows:
var Price = {};
var Name = {};
var Totaal = {};
$(function () {
var currencies = [
{value:'TEXT-STRING',data:'5.50)'},
{value:'TEXT-STRING2',data:'3.10)'},
];
$('#autocomplete').autocomplete({
lookup: currencies,
onSelect: function (suggestion) {
Price.fff = suggestion.data;
Name.fff = suggestion.value;
},
});
});
function addListItem() {
var write2 = Price.fff;
var write = $('#autocomplete').val();
var list = $('#itemList');
var item = $('<li><span class="list">' + write + '</span><button
class="delete">X</button></li>');
var autocomplete = $("#autocomplete");
if (write.length === 0 || write.length > 88) {
return false;
}
if (write == Name.fff) {
list.append(item);
list2.append(item2);
$(autocomplete).val('');
}
$(autocomplete).val('');
}
function deleteItem() {
$(this).parent().remove();
}
$(function () {
var add = $('#addItem');
var autocomplete = $('#autocomplete');
var list = $('#itemList');
add.on('click', addListItem);
list.on('click', '.delete', deleteItem);
autocomplete.on('keypress', function (e) {
if (e.which == 13) {
addListItem();
}
}
And my HTML looks like:
<body>
<div id="box-1"> </div>
<div id="box-2"> </div>
<div id="page">
<h1>Shop</h1>
</div>
<div id="main">
<div id="top">
<div id="form">
<div id="searchfield">
<input type="text" id="autocomplete" name="currency" class="biginput" placeholder="ADD ITEMS BELOW">
<input type="submit" id="addItem" value="+">
</div>
<div class="line"> </div>
</div>
<div id="bottom">
<div class="items">
<ul id="itemList">
</ul>
</div>
</div>

Keep added item in array with prices, so you can recalculate total at any time. Don't forget to remove it from array when removing from the list.
Don't keep data in DOM, use DOM only to display info that is in your model.

Related

Trying to turn onclick to enter key

I'm a beginner and I'm trying to help some special education students with a very basic budget calculator. I've seen similar questions to mine posted, but when I try those methods something always breaks and I'm having some trouble figuring it out.
Basically I need the onclick portion of the button that calls the function into action to actually respond to the enter key and not a click :-( Thank you very much in advance for any help that might be provided!!
<script>
function addTwoNumbers () {
var number1 = document.getElementById('box1').value;
var number2 = Number(document.getElementById('box2').value);
var sum = Number(number1) + number2;
document.getElementById('resultBox').value = sum;
if(sum<0) {
document.getElementById('resultBox').style.color = "red";
}
else{
document.getElementById('resultBox').style.color = "green";
}
document.getElementById('resultBox').style.visibility = 'visible';
document.getElementById('resultBox').value = sum
}
</script>
<script>
function subtractTwoNumbers () {
var number1 = document.getElementById('box1').value;
var number2 = Number(document.getElementById('box2').value);
var difference = Number(number1) - number2;
document.getElementById('resultBox').value = difference;
if(difference<0) {
document.getElementById('resultBox').style.color = "red";
}
else{
document.getElementById('resultBox').style.color = "green";
}
document.getElementById('resultBox').style.visibility = 'visible';
document.getElementById('resultBox').value = sum
}
</script>
<script>
function clearall() {
document.getElementById('box1').value = "";
document.getElementById('box2').value = "";
document.getElementById('resultBox').value = "";
}
</script>
<div id='calc' align="center"></div>
<h1>Calculator</h1>
<p>Enter budget <input type="text" id="box1"></p>
<p>Enter price   <input type="text" id="box2"></p>
<p>Press the equation key to see your results</p>
<div class="btn-group" style="width:100%">
<button style="width:33.3%" onclick="addTwoNumbers()">+</button>
<button style="width:33.3%" onclick="subtractTwoNumbers()">-</button>
<p>
<button style="width:67.5%" onclick="clearall()">clear</button>
</div>
<h3>Do you have enough?</h3>
<input type="text" id="resultBox"> <br/>
Instead of using the onclick attribute in the HTML, a more modern approach would be to create an event listener in your javascript.
I would give the buttons an ID. Then do something like this:
document.getElementById("clearBtn").addEventListener("click", clearAll);
There are all kinds of events you can listen for and I would guess you could find one that provides the behavior you are after.

Apps script return values from server function to html form

I need help of professionals at Apps script. I have the project implemented by web-app.
I wrote script on server-part
var url = "https://docs.google.com/spreadsheets/d/1s8l-8N8dI-GGJi_mmYs2f_88VBcnzWfv3YHgk1HvIh0/edit?usp=sharing";
var sprSRCH = SpreadsheetApp.openByUrl(url);
let sheetSRCHSSCC = sprSRCH.getSheetByName("PUTAWAY_TO");
function GetQ(){
var QPLAN = sheetSRCHSSCC.getRange("M2:M").getValues().filter(String).length;
var myArray = sheetSRCHSSCC.getRange("O2:O" + (QPLAN + 1)).getValues();
var QFACT = 0;
for (i = 0; i < myArray.length; i++) {
if (myArray[i] != "") {
QFACT += 1
}
}
}
I need to return values from this function to inputs:
QFACT to FACT
QPLAN to PLAN
<div class="input-field col s3">
<input disabled value="" id="PLAN" type="text" >
<label for="disabled">PLAN</label>
</div>
<div class="input-field col s3">
<input disabled value="" id="FACT" type="text" >
<label for="disabled">FACT</label>
</div>
I will be grateful for the help. I'm new at this))
If you are using Apps Script deploying Web App, I can see 2 possibilities :
1/ Get data at the loading of the page (and only at the loading) :
In code.gs :
function doGet() {
var tmp = HtmlService.createTemplateFromFile('page');
tmp.QFACT = "hello";
tmp.PLAN = "World!";
return tmp.evaluate();
}
In page.html :
<html>
<body>
<h5><?= QFACT ?></h5>
<h5><?= QPLAN ?></h5>
</body>
</html>
2/ If you need to refresh the data by click button, or something else, you will need to operate diffently :
Add a page-js.html to your project, and bind it at the end of your page.html
<html>
<body>
<h5 id="QFACT"></h5>
<h5 id="QPLAN"></h5>
</body>
<?!= include("page-js"); ?>
</html>
then in your page-js.html :
<script>
function refresh() {
google.script.run.withSuccessHandler(callback).refresh();
}
function callback(e) {
document.getElementById('QPLAN').innerHTML = e.QPLAN;
document.getElementById('QFACT').innerHTML = e.QFACT;
}
</script>
and finally add the refresh() function in your code.gs :
function refresh() {
var obj = {};
obj.QPLAN = "QPLAN";
obj.QFACT = "QFACT";
return obj;
}

Apps Script: Collect Form Input and Display Today's Total

First time poster here: I've created a web app in Apps Script where the user enters:
Date
Food
Quantity
...then the associated 'health points' are calculated and added to a spreadsheet in Google Sheets.
What I want to do is calculate and display the day's total and then recalculate and display whenever the form is submitted. I'm still a newer JS user, so I'm cheating a bit by calculating in Google Sheets. Here's what that formula looks like:
=sum(ArrayFormula(if(today()-1=Data!A:A,Data!B:B,0)))
..then I'm passing that as a template value. That works when loading the page, but I would like it to update whenever the form is submitted.
Do you have ideas on how to calculate today's total using a script instead of Sheets and recalculating/displaying when the form is submitted?
Update: I've attached the code. And here's the sheet: https://docs.google.com/spreadsheets/d/1pXtOAnVJOkz1DGKir79pxoMUG85LPSfoN4SSVUk0a1k/edit?usp=sharing
function doGet(request) {
var t = HtmlService.createTemplateFromFile('index');
var url = "https://docs.google.com/spreadsheets/d/1pXtOAnVJOkz1DGKir79pxoMUG85LPSfoN4SSVUk0a1k/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Points");
var total = ws.getRange(1,1,1,1).getValue();
var remaining = 25-total;
Logger.log(total);
Logger.log(remaining);
t.total = total;
t.remaining = remaining;
return t.evaluate();
}
function getLast() {
var url = "https://docs.google.com/spreadsheets/d/1pXtOAnVJOkz1DGKir79pxoMUG85LPSfoN4SSVUk0a1k/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
var last = ws.getLastRow();
Logger.log(last);
}
/* #Include JavaScript and CSS Files */
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
/* #Process Form */
function processForm(formObject) {
// (Calories * .0305) + (Sat Fat * .275) + (Sugar * .12) - (Protein * .098)
var smartpointsServing = Math.round((formObject.calories * .0305) + (formObject.satfat * .275) + (formObject.sugar * .12) - (formObject.protein * .098));
// var formattedDate = Utilities.formatDate(new Date(formObject.today), "GMT-6", "MM/dd/yyyy");
var url = "https://docs.google.com/spreadsheets/d/1pXtOAnVJOkz1DGKir79pxoMUG85LPSfoN4SSVUk0a1k/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Foods");
var ws2 = ss.getSheetByName("Data");
var newFoodHp = smartpointsServing*formObject.quantity;
if (formObject.new_food_name !== ""){
ws.appendRow([formObject.new_food_name,
smartpointsServing,
formObject.serving_size_no,
formObject.serving_size_unit,
formObject.calories,
formObject.satfat,
formObject.sugar,
formObject.protein]);
ws2.appendRow([formObject.today,
newFoodHp,
formObject.food_name,
formObject.quantity]);}
else {
ws2.appendRow([formObject.today,
formObject.smartpoints,
formObject.food_name,
formObject.quantity]);
}
}
function getSmartPoints(foodLookup){
var url = "https://docs.google.com/spreadsheets/d/1pXtOAnVJOkz1DGKir79pxoMUG85LPSfoN4SSVUk0a1k/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Foods");
var data = ws.getRange(2, 1, ws.getLastRow()-1, 2).getValues();
var foodList = data.map(function(r){ return r[0]; });
var smartpointsPerServing = data.map(function(r){ return r[1]; });
var position = foodList.indexOf(foodLookup);
if (position >-1){
return smartpointsPerServing[position];
} else {
return 'Food Not Found';
}
}
function returnDropDownArray() {
var url = "https://docs.google.com/spreadsheets/d/1pXtOAnVJOkz1DGKir79pxoMUG85LPSfoN4SSVUk0a1k/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Foods");
var array = ws.getRange(2,1,ws.getLastRow()-1,1).getValues().sort();
Logger.log(array);
return ws.getRange(2,1,ws.getLastRow()-1,1).getValues().sort();
}
<!DOCTYPE html>
<html>
<head>
<!--Install Bootstrap-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<?!= include('JavaScript'); ?>
<style>
body {
color: blue;
}
</style>
</head>
<body>
<p id="date"></p>
<div class="container">
<form id="myForm" onsubmit="handleFormSubmit(this)">
<h1><b>Health Points</b></h1>
<div class = "row">
<div class="col-md-2">
<label for="today">Date</label>
<input type="date" class="form-control" id="today" name="today" required>
</div>
</div>
<div class="row">
<div class="col-md-3">
<label for="food_name">Food Name:</label><br>
<select class="form-control" id="food_name" name="food_name" value="Select Food" required>
</select>
</div>
<div class="col-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="add" name="add">
<label class="form-check-label" for="flexCheckDefault">
Add New Food?
</label>
</div>
</div></div>
<div class="row">
<div class="col-md-4">
<label for="quantity">Quantity:</label><br>
<input id="quantity" type="number" step=".5" value="1" name="quantity">
</div>
</div><br>
<div class="row">
<div class="col-md-4">
<input id="smartpoints" type="text" placeholder="Health Points" name="smartpoints" readonly>
</div>
</div>
<!-- <br>
<div id="templateTotal"><p>Today's Total: <strong><?= total ?>/25</strong><br>
Points Remaining: <strong><?= remaining ?></strong></p></div> -->
<!-- Start section for adding foods -->
<div id="addfood" style="display:none;">
<br>
<div class="col-md-6">
<div class="card">
<div class="card-header">
Add a Food
</div>
<div class="container">
<div class="row">
<div class="col-md-4">
<label for="new_food_name">New Food Name:</label><br>
<input type="text" id="new_food_name" name="new_food_name">
</div>
</div>
<div class="row">
<div class="col-md-4">
<label for="serving_size_no">Serving Size #:</label>
<input type="number" id="serving_size_no" name="serving_size_no" step=".25">
</div>
</div>
<div class="row">
<div class="col-md-4">
<label for="serving_size_unit">Serving Size Unit:</label>
<input list="serving_size_unit_list" id="serving_size_unit" name="serving_size_unit">
<datalist id="serving_size_unit_list">
<option value="Cup(s)">
<option value="Ounce(s)">
<option value="Tbsp(s)">
<option value="Tsp(s)">
<option value="Gram(s)">
</datalist>
</div>
</div>
<div class="row">
<div class="col-md-4">
<label for="calories">Calories:</label>
<input type="number" id="calories" name="calories" step="1">
</div>
</div>
<div class="row">
<div class="col-md-4">
<label for="satfat">Saturated Fat:</label>
<input type="number" id="satfat" name="satfat">
</div>
</div>
<div class="row">
<div class="col-md-4">
<label for="satfat">Sugar:</label>
<input type="number" id="sugar" name="sugar">
</div>
</div>
<div class="row">
<div class="col-md-4">
<label for="protein">Protein:</label>
<input type="number" id="protein" name="protein">
</div>
</div><br>
</div>
</div>
</div></div><br>
<!-- End section for adding foods -->
<div class="col-md-4">
<button type="submit" class="btn btn-primary btn-block">Submit</button>
</div>
</form>
<div id="output"></div>
</div>
<script type="text/javascript">
document.getElementById("add").onchange = function(){
if (document.getElementById("add").checked) {
addfood.style.display = "block";
} else {
addfood.style.display = "none";
}
};
document.getElementById('food_name').onclick = function() {
var foodLookup = this.value;
google.script.run.withSuccessHandler(populateSmartpoints).getSmartPoints(foodLookup);
function populateSmartpoints(smartpointsPerServing){
var quantity = document.getElementById('quantity').value;
document.getElementById('smartpoints').value=smartpointsPerServing*quantity;
};
}
// Run function afterPageLoads once the page has loaded
document.addEventListener("DOMContentLoaded",afterPageLoads);
// Get drop down array for food names if that function is successful
function afterPageLoads() {
google.script.run.withSuccessHandler(afterDropDownArrayReturned).returnDropDownArray();
}
// Populate food name drop down with array from Google Sheets
function afterDropDownArrayReturned(arrayOfArrays) {
var item = document.getElementById("food_name");
console.log(item);
arrayOfArrays.forEach(function(r){
var option = document.createElement("option");
option.textContent = r[0];
item.appendChild(option);
});
}
// Update Smart Points if quantity is updated
document.getElementById('quantity').onchange = function() {
var sp = document.getElementById('smartpoints').value;
var quantity = document.getElementById('quantity').value;
document.getElementById('smartpoints').value=sp*quantity;
}
// Update food name if new food is added
document.getElementById('new_food_name').onchange = function() {
var newOption = document.getElementById('new_food_name').value;
if (newOption !==""){
var item = document.getElementById("food_name");
var option = document.createElement("option");
option.textContent = newOption;
item.appendChild(option);
var val = item.value;
item.value = newOption;
}
}
//Set today as the default date
n = new Date();
y = n.getFullYear();
m = n.getMonth() + 1;
d = n.getDate();
document.getElementById("today").value = y + "-" + m + "-" + d;
//Reload Page
</script>
</body>
</html>
This will sum column B in a linked sheet to a form from row 2 to the submitted row.
function onFormSubmit(e) {
const sh=e.range.getSheet();
const vals=sh.getRange(2,2,e.range.getRow()-1).getValues().flat();
let sum=vals.reduce(function(a,c){return a+=c;},0);
Logger.log(sum);
}
Remember the trigger requires an installable trigger.

Splitting up results of knockout data into 2 columns

Was curious if there was an easy way to split up the following code into 2 columns via Knockout and HTML. I know how to do it in the CSS but really it's just to split results 1-5 and 6-9. Here's my code. Screenshot attached as well. Thank you
<div class="item summary">
<h3> <?=l(479)?> </h3>
<div data-bind="foreach:$data.summary">
<div>
<span data-bind="text:$data.sequence + '.'"></span>
<span data-bind="text:$data.label + ':'"></span>
<span data-bind="text:$data.value"></span>
</div>
</div>
</div>
If the length isn't going to change you can duplicate the markup for each block and add a slice(). It's not the most elegant but it's probably the easiest.
<!-- ko if: summary && summary.length > 0 -->
<div data-bind="foreach: $data.summary.slice(0,5)">
...
<div data-bind="foreach: $data.summary.slice(5)">
...
<!-- /ko -->
If you want something a little more dynamic you can create a computed function that splits your array into multiple pieces and use a nested foreach instead:
function viewModel(){
var self = this;
this.summary = [
new Summary(1),
new Summary(2),
new Summary(3),
new Summary(4),
new Summary(5),
];
this.summaryBlocks = ko.computed(function(){
if(self.summary && self.summary.length > 0){
var size = self.summary.length / 2;
return [
self.summary.slice(0,size),
self.summary.slice(size)
];
}else{
return [];
}
});
}
function Summary(val){
this.sequence = 'sequence';
this.label = 'label';
this.value = val;
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="item summary">
<h3> <?=l(479)?> </h3>
<div data-bind="foreach: summaryBlocks">
<div style="display:inline-block; vertical-align:top;" data-bind="foreach:$data">
<div>
<span data-bind="text:$data.sequence + '.'"></span>
<span data-bind="text:$data.label + ':'"></span>
<span data-bind="text:$data.value"></span>
</div>
</div>
</div>
</div>
EDIT: Another snippet for dealing with a variable number of columns
function viewModel() {
var self = this;
this.columns = ko.observable(1);
this.summary = [new Summary(1), new Summary(2), new Summary(3), new Summary(4), new Summary(5), new Summary(6), new Summary(7), new Summary(8), new Summary(9)];
this.summaryBlocks = ko.pureComputed(function() {
var result = [];
for (var i = 0; i < self.columns(); i++) result.push([]);
if (self.summary && self.summary.length > 0) {
for (var i = 0; i < self.summary.length; i++) {
var col = i % self.columns();
result[col].push(self.summary[i]);
}
}
return result;
});
}
function Summary(val) {
this.sequence = 'sequence';
this.label = 'label';
this.value = val;
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
columns: <span data-bind="text: columns"></span>
<br/><input type="range" min=1 max=5 data-bind="value: columns" />
<div class="item summary">
<div data-bind="foreach: summaryBlocks">
<div style="display:inline-block; vertical-align:top;" data-bind="foreach:$data">
<div style="border: 1px dashed blue;">
<span data-bind="text:'item ' + value"></span>
</div>
</div>
</div>
</div>

Swipe to Reveal is not working

I have implemented a swipe to reveal Oracle JET component.
Below is my Js code
this.action = ko.observable("No action taken yet");
this.handleReady = function()
{
// register swipe to reveal for all new list items
$("#listview").find(".item-marker").each(function(index)
{
var item = $(this);
var id = item.prop("id");
var startOffcanvas = item.find(".oj-offcanvas-start").first();
var endOffcanvas = item.find(".oj-offcanvas-end").first();
// setup swipe actions
oj.SwipeToRevealUtils.setupSwipeActions(startOffcanvas);
oj.SwipeToRevealUtils.setupSwipeActions(endOffcanvas);
// make sure listener only registered once
endOffcanvas.off("ojdefaultaction");
endOffcanvas.on("ojdefaultaction", function()
{
self.handleDefaultAction(item);
});
});
};
this.handleDestroy = function()
{
// register swipe to reveal for all new list items
$("#listview").find(".item-marker").each(function(index)
{
var startOffcanvas = $(this).find(".oj-offcanvas-start").first();
var endOffcanvas = $(this).find(".oj-offcanvas-end").first();
oj.SwipeToRevealUtils.tearDownSwipeActions(startOffcanvas);
oj.SwipeToRevealUtils.tearDownSwipeActions(endOffcanvas);
});
};
this.handleMenuBeforeOpen = function(event, ui)
{
var target = event.originalEvent.target;
var context = $("#listview").ojListView("getContextByNode", target);
if (context != null)
{
self.currentItem = $("#"+context['key']);
}
else
{
self.currentItem = null;
}
};
this.handleMenuItemSelect = function(event, ui)
{
var id = ui.item.prop("id");
if (id == "read")
self.handleRead();
else if (id == "more1" || id == "more2")
self.handleMore();
else if (id == "tag")
self.handleFlag();
else if (id == "delete")
self.handleTrash();
};
this.closeToolbar = function(which, item)
{
var toolbarId = "#"+which+"_toolbar_"+item.prop("id");
var drawer = {"displayMode": "push", "selector": toolbarId};
oj.OffcanvasUtils.close(drawer);
};
this.handleAction = function(which, action, event)
{
if (event != null)
{
self.currentItem = $(event.target).closest(".item-marker");
// offcanvas won't be open for default action case
if (action != "default")
self.closeToolbar(which, self.currentItem);
}
if (self.currentItem != null)
self.action("Handle "+action+" action on: "+self.currentItem.prop("id"));
};
this.handleRead = function(data, event)
{
self.handleAction("first", "read", event);
};
this.handleMore = function(data, event)
{
self.handleAction("second", "more", event);
};
this.handleFlag = function(data, event)
{
self.handleAction("second", "Rejected", event);
};
this.handleTrash = function(data, event)
{
self.handleAction("second", "Accepted", event);
self.remove(self.currentItem);
};
this.handleDefaultAction = function(item)
{
self.currentItem = item;
self.handleAction("second", "default");
self.remove(item);
};
this.remove = function(item)
{
// unregister swipe to reveal for removed item
var startOffcanvas = item.find(".oj-offcanvas-start").first();
var endOffcanvas = item.find(".oj-offcanvas-end").first();
oj.SwipeToRevealUtils.tearDownSwipeActions(startOffcanvas);
oj.SwipeToRevealUtils.tearDownSwipeActions(endOffcanvas);
alert(JSON.stringify(self.allItems()));
alert(item.toString());
self.allItems.remove(function(current)
{
return (current.id == item.prop("id"));
});
};
}
return PeopleViewModel;
});
HTML code:
<ul id="listview"
data-bind="ojComponent: {component: 'ojListView',
data: listViewDataSource,
item: {template: 'peoplelist_template'},
selectionMode: 'single',
ready: handleReady,
destroy: handleDestroy,
optionChange: changeHandler,
rootAttributes: {style: 'width:100%;height:100vh;overflow:auto; margin-top: 5px'},
scrollPolicy: 'loadMoreOnScroll',
scrollPolicyOptions: {fetchSize: 10}}">
</ul>
<script id="peoplelist_template">
<div style="padding:0.8571rem">
<div class="oj-flex oj-flex-items-pad">
<div class="oj-flex-item oj-lg-4 oj-md-4">
<img alt="employee image" class="demo-circular demo-employee-photo" style="float:left;" data-bind="attr: {src: $parent.getPhoto($data['name'])}"/>
<h2 class="demo-employee-name" data-bind="text: $data['from']"></h2>
<div class="demo-employee-title" data-bind="text: $data['title']"></div>
<div class="demo-employee-dept" data-bind="text: $data['deptName']"></div>
</div>
<div style="line-height: 1.5em; height: 3em; overflow: hidden; text-overflow: ellipsis" class="oj-text-sm oj-text-secondary-color" data-bind="text: $data['content']"></div>
</div>
</div>
<div tabIndex="-1" data-bind="attr: {id: 'first_toolbar_'+empId}" class="oj-offcanvas-start" style="width:75px">
<div data-bind="click:$parent.handleRead">
<div class="oj-flex-bar" style="height:100%">
<div class="oj-flex-bar-center-absolute">
<div class="oj-flex oj-sm-flex-direction-column">
<div title=".demo-library-icon-24" role="img" class="oj-flex-item demo-library-icon-24 demo-icon-font-24"></div>
<div style="padding-top: 10px" class="oj-flex-item">Read</div>
</div>
</div>
</div>
</div>
</div>
<div tabIndex="-1" data-bind="attr: {id: 'second_toolbar_'+empId}" class="oj-offcanvas-end" style="width:225px">
<div class="oj-swipetoreveal-more" data-bind="click: $parent.handleMore">
<div class="oj-flex-bar" style="height:100%">
<div class="oj-flex-bar-center-absolute">
<div class="oj-flex oj-sm-flex-direction-column">
<div title=".demo-library-icon-24" role="img" class="oj-flex-item fa fa-bars"></div>
<div style="padding-top: 10px" class="oj-flex-item">More</div>
</div>
</div>
</div>
</div>
<div style="background-color:#b81900" data-bind="click: $parent.handleFlag" class="oj-swipetoreveal-flag">
<div class="oj-flex-bar" style="height:100%">
<div class="oj-flex-bar-center-absolute">
<div class="oj-flex oj-sm-flex-direction-column">
<div title=".demo-library-icon-24" role="img" class="oj-flex-item fa fa-times"></div>
<div style="padding-top: 10px" class="oj-flex-item">Reject</div>
</div>
</div>
</div>
</div>
<div style="background-color:#009638" data-bind="click: $parent.handleTrash" class="oj-swipetoreveal-alert oj-swipetoreveal-default">
<div class="oj-flex-bar" style="height:100%">
<div class="oj-flex-bar-center-absolute">
<div class="oj-flex oj-sm-flex-direction-column">
<div title=".demo-library-icon-24" role="img" class="oj-flex-item fa fa-check"></div>
<div style="padding-top: 10px" class="oj-flex-item">Approve</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</li>
</script>
Actual problem is the listItem is not getting removed while approving.(The Approve div is call Handletrash function).
I dont know where I went wrong ??could anyone help me to solve this issue??
There's a lot of code here, which makes it hard to understand what everything is intended to do, and harder to pinpoint what the problem might be. That's why it's best to make a Minimal, Complete, and Verifiable Example. Also, in the process of removing all the code that does not directly affect your problem, you may solve it yourself.
I notice in your code that you have a number of jQuery calls. That's a significant red flag. Your contract with Knockout is that you will manipulate your data model and Knockout will use it to control the DOM. If you "go behind Knockout's back" and manipulate the DOM yourself, you and Knockout are going to be stepping on each other's toes.
Knockout provides two ways for you to customize how it manipulates the DOM: animated transitions and custom bindings. "Swipe to reveal" sounds like a transition to me, but looking at your code, it appears there's a whole lifecycle involved, so I think you need to make a custom binding handler.
All of your DOM-manipulating code should be inside the binding handler, and all of it should be restricted to the element of the binding handler. There should be no document-wide selectors.