Computed value not updating on changing text box value in knockout javascript - javascript

http://jsfiddle.net/Kapil_B/vz3r0bs3/9/
In this fiddle I am trying to update the formattedPrice2 value on changing the rates in the textbox.I am able to get the updated price but the price1 is not getting updated value.
Can you please tell me the reason why the price1 value is not getting updated? That is why formattedPrice2 is not getting updated.
<select data-bind="options: $root.newLot, value: dropdownAValue, optionsText: 'type'"></select>
<table align="left">
<thead>
<tr align="left">
<th width="10%">Pair</th>
<th width="10%">Rate</th>
<th width="10%">formattedPrice2</th>
</tr>
</thead>
<!-- Todo: Generate table body -->
<tbody data-bind="foreach:curArray">
<tr>
<td data-bind="text: rate().pair"></td>
<td> <input data-bind="value: myQuote, valueUpdate:'afterkeydown'" />
</td>
<td data-bind="text: formattedPrice2"></td>
</tr>
</tbody>
</table>
// Class to represent a row in the price calculation grid
function PriceCalculation(rate, myQuote, newPairs, nl, currentlotvalue) {
var self = this;
self.rate = ko.observable(rate);
self.newPairs = newPairs;
self.nl = ko.observable(nl);
self.myQuote = ko.observable(myQuote);
self.currentlotvalue = currentlotvalue;
self.leverage = self.rate().leverage;
self.formattedPrice2 = ko.computed(function () {
var cur = self.rate().pair;
//var price = self.rate().price;
var price = self.myQuote();
var pip = 1;
var lot1 = self.currentlotvalue;
var JPlot = lot1 * 100;
if (cur.indexOf("/USD") > -1) {
pip = lot1;
} else if (cur.indexOf("/JPY") > -1) {
pip = JPlot / price;
} else if (cur.indexOf("USD/") > -1) {
pip = lot1 / price;
} else {
var base = cur.split("/")[0];
var counter = cur.split("/")[1];
for (var i = 0; i < self.newPairs.length; i++) {
var base1 = self.newPairs[i].pair.split("/")[0];
var counter1 = self.newPairs[i].pair.split("/")[1];
var price1 = self.newPairs[i].price;
alert(price1);
if (base1 == "USD") {
if ((self.newPairs[i].pair) == ("USD/" + counter)) {
pip = lot1 / price1;
}
} else if (counter1 == "USD") {
if ((self.newPairs[i].pair) == (counter + "/USD")) {
pip = lot1 * price1;
}
}
}
}
//alert(pip? "$" + pip.toFixed(2): "None");
return pip ? "$" + pip.toFixed(2) : "None";
});
}
// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
var self = this;
self.curArray = ko.observableArray([]);
self.rates = ko.observableArray([]);
// Non-editable catalog data - would come from the server
self.rates = [ {
pair: "EUR/HUF",
price: 318.815,
leverage: "20:1*"
}, {
pair: "USD/HUF",
price: 265.13,
leverage: "20:1*"
}, {
pair: "XAG/USD",
price: 15.734,
leverage: "1:1*"
}, {
pair: "XAU/USD",
price: 1184.43,
leverage: "1:1*"
}];
self.newLot = [{
type: "Micro",
lotSize: 0.1
}, {
type: "Mini",
lotSize: 1
}, {
type: "Standard",
lotSize: 10
}];
self.newlots = ko.observableArray(self.newLot);
self.dropdownAValue = ko.observable(self.newlots);
var currentlotvalue = 0.1;
self.dropdownAValue.subscribe(function () {
if (self.dropdownAValue().type == "Micro") {
//alert("Micro");
currentlotvalue = 0.1;
} else if (self.dropdownAValue().type == "Mini") {
//alert("Mini");
currentlotvalue = 1;
} else if (self.dropdownAValue().type == "Standard") {
//alert("Standard");
currentlotvalue = 10;
}
var newItems = ko.utils.arrayMap(self.rates, function (item) {
return new PriceCalculation(item, item.price, self.rates, self.newLot[0], currentlotvalue)
});
self.curArray(newItems);
},this, "change");
}
ko.applyBindings(new ReservationsViewModel());

Related

Javascript for card shuffle failing

Over my head with javascript. I'm trying to get the cards to shuffle when clicking next.
Currently, it moves forward with one random shuffle and stops. Back and forward buttons then no longer work at that point.
Please help—many thanks.
When I'm lost and unsure what sample of the code to pinpoint, the captions go up to 499. The sample is also here: https://rrrhhhhhhhhh.github.io/sentences/
Very new to javascript. So any help is greatly appreciated. Very open to better ways to achieve this???
How I have it set up:
HTML:
var r = -1;
var mx = 499; // maximum
var a = new Array();
function AddNumsToDict(){
var m,n,i,j;
i = 0;
j = 0;
while (i <= 499)
{
m = (500 * Math.random()) + 1;
n = Math.floor(m);
for (j=0;j<=499;j++)
{
if (a[j] == (n-1))
{
j = -1;
break;
}
}
if (j != -1)
{
//a.push(n-1);
a[i] = (n-1);
i++;
j=0;
}
}
return;
}
function startup()
{
writit('SENTENCES<br><br><br>Robert Grenier', 'test');
SetCookie("pg", -1);
AddNumsToDict();
}
function SetCookie(sName, sValue)
{
document.cookie = sName + "=" + escape(sValue) + ";"
}
function GetCookie(sName)
{
// cookies are separated by semicolons
var aCookie = document.cookie.split("; ");
for (var i=0; i < aCookie.length; i++)
{
// a name/value pair (a crumb) is separated by an equal sign
var aCrumb = aCookie[i].split("=");
if (sName == aCrumb[0])
return unescape(aCrumb[1]);
}
// a cookie with the requested name does not exist
return null;
}
function doBack(){
//var oPrev = xbElem('prev');
//var oNxt = xbElem('nxt');
//if ((oNxt) && (oPrev))
//{
var num = GetCookie("pg");
if (num == mx){ //maximum
SetCookie("pg",parseInt(num) - 1);
num = GetCookie("pg");
}
// oNxt.disabled = false;
// if (num <= 1){
// oPrev.disabled = true;
// }
if (num >= 1){
num--;
writit(Caption[a[num]], 'test');
SetCookie("pg",num);
}
//}
}
function doNext(){
//var oPrev = xbElem('prev');
//var oNxt = xbElem('nxt');
// if ((oNxt) && (oPrev))
// {
var num = GetCookie("pg");
// if (num > -1){
// oPrev.disabled = false;
// }
// else{
// oPrev.disabled = true;
// }
// if (num >= parseInt(mx)-1){ //maximum - 1
// oNxt.disabled = true;
// }
// else {
// oNxt.disabled = false;
// }
if (num <= parseInt(mx)-2){
num++;
writit(Caption[a[num]],'test');
SetCookie("pg",num);
}
// }
}
function writit(text,id)
{
if (document.getElementById)
{
x = document.getElementById(id);
x.innerHTML = '';
x.innerHTML = text;
}
else if (document.all)
{
x = document.all[id];
x.innerHTML = text;
}
else if (document.layers)
{
x = document.layers[id];
l = (480-(getNumLines(text)*8))/2;
w = (764-(getWidestLine(text)*8))/2;
text2 = '<td id=rel align="center" CLASS="testclass" style="font:12px courier,courier new;padding-left:' + w.toString() + 'px' + ';padding-top:' + l.toString() + 'px' + '">' + text + '</td>';
x.document.open();
x.document.write(text2);
x.document.close();
}
}
function getNumLines(mystr)
{
var a = mystr.split("<br>")
return(a.length);
}
function getWidestLine(mystr)
{
if (mystr.indexOf(" ") != -1)
{
re = / */g;
mystr = mystr.replace(re,"Z");
//alert(mystr);
}
if (mystr.indexOf("<u>") != -1)
{
re = /<u>*/g;
mystr = mystr.replace(re, "");
re = /<\/u>*/g;
mystr = mystr.replace(re, "");
}
if (mystr.indexOf("<br>") != -1)
{
var ss, t;
var lngest;
ss = mystr.split("<br>");
lngest = ss[0].length;
for (t=0; t < ss.length; t++)
{
if (ss[t].length > lngest)
{
lngest = ss[t].length;
}
}
}
else {
lngest = mystr.length;
}
return(lngest);
}
// -->
</script>
<body bgcolor="gainsboro" onload="startup();">
<table bgcolor="white" border height="480px" width="764px" cellpadding="0" cellspacing="0">
<tr>
<td align="center">
<table nowrap>
<tr>
<td><img width="700px" height="1px" src="./resources/images/w.gif"></td>
<td>
<div class="testclass" id="test"></div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<center>
<form>
<p>
<input type="button" onclick="doBack(); return false" value="Back">
<input type="button" onclick="doNext(); return false" value="Next">
JS:
var _____WB$wombat$assign$function_____ = function(name) {return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name)) || self[name]; };
if (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; return this; } }
{
let window = _____WB$wombat$assign$function_____("window");
let self = _____WB$wombat$assign$function_____("self");
let document = _____WB$wombat$assign$function_____("document");
let location = _____WB$wombat$assign$function_____("location");
let top = _____WB$wombat$assign$function_____("top");
let parent = _____WB$wombat$assign$function_____("parent");
let frames = _____WB$wombat$assign$function_____("frames");
let opener = _____WB$wombat$assign$function_____("opener");
function CaptionArray(len) {
this.length=len
}
Caption = new CaptionArray(499);
Caption[0] = "leaf and the ants as latterly"
Caption[1] = "thought<br>living in<br>Davis would<br>be ok"
Caption[2] = "sure arm today"
Caption[3] = "AMY<br><br>no we<br>both do<br>different<br>songs together"
Caption[4] = "much of anything she doesn't like that at all"
Caption[5] = "SUNG AS LAKE<br><br><br>that never wanted back to come"
Caption[6] = "five sound shut doors"
Caption[7] = "oh<br>my nose is<br>so<br>red<br>Obediah<br>dear"
Caption[8] = "these<br>cubes<br>have been<br>on the floor"
Caption[9] = "sweating importunate"
Caption[10] = "all over noises phone rings"
Caption[11] = "I think this is the water supply for Lake Johnsbury"
Caption[12] = "Paw so greasy"
Caption[13] = "BLACK & WHITE RAIN<br><br><br>clear water grey drops<br><br><br>on windshields in a line<br><br><br>of cars progressing slowly<br><br><br>with windshield wipers wiping"
Caption[14] = "EMILY<br><br>Roger,<br><br>are you<br><br>thinking of me"
Caption[15] = "STICKS<br><br><br>rhythm is inside the sound like another"
Caption[16] = "I think their dog always barks when coming back from the woods"
Caption[17] = "weren't there<br><br>conversations"
Caption[18] = "LOOKING AT FIRE<br><br><u>ashes</u> to ashes<br><br>looking at the fire<br><br>at has been added"
Caption[19] = "a the bank"
}

VueJs renders all elements upon a single change

I have the following sample grid in which I push some new values to the bound list.
Press anywhere in the grid to push a new value to the grid.
As you can see in the fiddle, the updated cell will have a green color for 500 ms, and all the re-rendered elements will have yellow color.
The question is how we should configure Vue component so that it only re-render the changed element instead of them all?
If you look at the fiddle console output, you will see numbers like (13001, 26001, ...) and this equals to the number of all cells (1000 rows x 13 columns).
.yellow {
background-color: yellow;
}
.pushed {
background-color: lightgreen
}
<script src="https://unpkg.com/vue">
var globalCount = 0;
</script>
<head>
<title>Vue Render Performance</title>
</head>
<div id="demo">
<demo-grid :data="gridData" :columns="gridColumns"> </demo-grid>
</div>
<script type="text/x-template" id="grid-template">
<table #click="pushData()">
<thead>
<tr>
<th v-for="key in columns">
{{key}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(entry, i) in data">
<td v-for="(key, j) in columns" :id="'a'+i +'_'+j">
{{renderMe(entry[key], 'a'+i +'_'+j)}}
</td>
</tr>
</tbody>
</table>
</script>
<script>
const data = newData(1000);
var renderedCount = 0;
var startTime = performance.now();
Vue.component('demo-grid', {
props: {
data: Array,
columns: Array,
renderCount: Object,
},
template: '#grid-template',
methods: {
renderMe(el, id) {
const elm = document.getElementById(id);
if (elm) {
elm.className += " yellow";
}
if (!renderedCount) {
renderedCount = 0
} else {
renderedCount++;
}
return el;
},
pushData() {
debugger
var push = function() {
let cols = ["Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7", "Col8", "Col9", "Col10", "Col11", "Col12", "Col13"];
var t0 = performance.now();
for (let i = 0; i < 1; i++) {
let newVal = Math.random() * 10000,
row = Math.round(Math.random() * 1000),
cellIndex = Math.floor(Math.random() * cols.length);
cell = cols[cellIndex];
if (data[row])
data[row][cell] = newVal;
var el = document.querySelector('tbody tr:nth-child(' + row + ') td:nth-child(' +
cellIndex +
')');
if (el) {
el.className = 'pushed';
el.scrollIntoView();
var t = function() {
if (el) {
el.className = '';
}
clearTimeout(t);
};
setTimeout(t, 500);
}
console.log('pushed to cell [' + row + ',' + cellIndex + '] :' + newVal);
console.log('Rendered Count: ' + renderedCount)
renderedCount++;
};
var t1 = performance.now();
console.log(t1 - t0)
};
push();
}
}
});
// bootstrap the demo
var demo = new Vue({
el: '#demo',
data: {
searchQuery: '',
gridColumns: ["Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7", "Col8", "Col9", "Col10", "Col11", "Col12", "Col13"],
gridData: data
}
})
Vue.config.devtools = true;
function newData(count) {
const data = [];
for (let i = 0; i < count; i++) {
data.push({
Col1: "Record",
Col2: 818959475,
Col3: 467587749,
Col4: 438,
Col5: 439,
Col6: 440,
Col7: 2.1,
Col8: 436.2,
Col9: 2.4,
Col10: 5770,
Col11: 5771,
Col12: 5772,
Col13: 5773
});
}
return data;
}
</script>
When you don't want to re-render and entire list of information, the typical way to handle it is to push the things that need to re-render into a component. Here is an updated version of your code that pushes the rows into a component and renders a fraction of what you were doing before.
Vue.component("demo-row", {
props:["entry", "columns", "rowIndex"],
template:`
<tr>
<td v-for="(key, j) in columns" :id="'a'+rowIndex +'_'+j">
{{renderMe(entry[key], 'a'+rowIndex +'_'+j)}}
</td>
</tr>
`,
methods:{
renderMe(el, id) {
const elm = document.getElementById(id);
if (elm) {
elm.className += " yellow";
}
if (!renderedCount) {
renderedCount = 0
} else {
renderedCount++;
}
return el;
},
}
})
Vue.component('demo-grid', {
props: {
items: Array,
columns: Array
},
template: '#grid-template',
methods: {
pushData() {
this.$parent.pushData(this.$parent.gridItems, this.$parent.gridColumns);
}
}
});
Example codepen.
Note, I did not change anything else that you are doing that could probably be done more idiomatically in Vue, I just wanted to demonstrate that there is no need for everything to re-render.

How to filter Table row with multiple condition .ie on checkbox selection show respected row. each checkbox represent Column and row value

I have a table with some dynamic data, and columns as Name,Location, Salary. Problem i am facing in Step 2 i.e multiple condition check. Heres the step by step code.
JS Fiddle Demo
Step 1-
Auto generate Filters i.e dynamically add Checkboxes, depend on table row values
autoFilterItem("filterDiv");
Above function generate dynamic checkboxes, logic is it loop over table, read values row by row and return unique value array and generate checkbox respectively, currently am doing for 2 cols having class loc,sal.
Step 2-
Checkbox change event, depend on status (checked/unchekced) table rows will be hide/show .
The problem i am facing is, if user checked 100 ( class as sal), and Kerala ( class as loc) is unchecked then row having kerala should be hide.
For hide and show am adding/removing class .hideRow
///STEP TWO
// On any checkbox clicked returns desired out
$("body").on('change', '.chk', function () {
var arrObj = [],
arrCheckedValueCLass = [];
var objCheckedData = {};
$("#filterDiv .chk").each(function (index, val) {
var sf = $(this);
if (sf.is(":checked")) {
var sf = $(this);
arrObj.push({
dataValue: $(sf).attr('data-value'),
dataClass: $(sf).attr('data-class')
});
}
});
var self = $(this);
var getClassName = self.attr("data-class");
var matchTextValue = $.trim(self.attr("data-value"));
if (self.is(":checked")) {
if (matchTextValue == "All") {
$(".chk").prop('checked', true);
}
$("." + getClassName).each(function () {
var innerSelf = $(this);
var gVal = $.trim(innerSelf.html());
if (matchTextValue == "All") {
innerSelf.closest("tr").removeClass("hideRow");
} else {
if (matchTextValue === gVal) {
console.log("checked and matchTextValue");
var i = 0,
lg = arrObj.length;
var flagSet = false;
for (i; i < lg; ++i) {
var objValue = arrObj[i].dataValue;
var objClass = arrObj[i].dataClass;
if (getClassName != objClass) {
var prevDataCheck = $.trim(innerSelf.closest("tr").find("." + objClass).html());
if (prevDataCheck == objValue) {
flagSet = true;
return true;
}
}
}
if (!flagSet) {
innerSelf.closest("tr").removeClass("hideRow");
innerSelf.closest("tr").addClass(getClassName + "_X");
}
}
}
});
} else {
if (matchTextValue == "All") {
$(".chk").prop('checked', false);
}
$("." + getClassName).each(function () {
var innerSelf = $(this);
var gVal = $.trim(innerSelf.html());
if (matchTextValue === gVal) {
innerSelf.closest("tr").addClass("hideRow");
innerSelf.closest("tr").removeClass(getClassName + "_X");
}
});
}
});
<div id="filterDiv"></div>
<button>Click</button>
<br>
<div id="tableContainer">
<table id="myTable">
<thead>
<tr>
<th data-name='name'>Name</th>
<th data-loc='Location'>Location</th>
<th data-sal='salary'>Salary</th>
<th data-sts='Active'>Active</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name">James</td>
<td class="loc">Mumbai</td>
<td class="sal">500</td>
<td class="sts">Yes</td>
</tr>
<tr>
<td class="name">Joseph</td>
<td class="loc">Kerala</td>
<td class="sal">100</td>
<td class="sts">No</td>
</tr>
<tr>
<td class="name">Jack</td>
<td class="loc">Delhi</td>
<td class="sal">500</td>
<td class="sts">Yes</td>
</tr>
<tr>
<td class="name">Andrea</td>
<td class="loc">Mumbai</td>
<td class="sal">1000</td>
<td class="sts">No</td>
</tr>
<tr>
<td class="name">David</td>
<td class="loc">Delhi</td>
<td class="sal">100</td>
<td class="sts">No</td>
</tr>
<tr>
<td class="name">David</td>
<td class="loc">Delhi</td>
<td class="sal">99900</td>
<td class="sts">No</td>
</tr>
</tbody>
</table>
</div>
I have created the fiddle from the things that you noted and able to produce the result( that is, if user checked 100 ( class as sal), and Kerala ( class as loc) is unchecked then row having kerala should be hide.)
I do not how efficient the solution is.There may be more efficient way to acheive that but anyway below is the js code.
$(document).ready(function () {
//STEP ONE STARTS
// This function generate checkbox from table data, which will be used for filteration
autoFilterItem("filterDiv");
function autoFilterItem(idOfHolderDiv) {
$("#" + idOfHolderDiv).empty();
var arr1 = [];
$(".sal").each(function () {
arr1.push($.trim($(this).html()));
});
var arrNew = unique(arr1).sort(function (a, b) {
return a - b
});
$.each(arrNew, function (i, val) {
$("<input/>", {
"type": "checkbox",
"class": "chk",
"data-class": "sal",
"data-value": val,
"id": "chk" + val,
"checked": "checked"
}).appendTo("#" + idOfHolderDiv).wrap("<div></div>").after(val);
});
$("#" + idOfHolderDiv).append("<hr>");
var arr2 = [];
$(".loc").each(function () {
arr2.push($.trim($(this).html()));
});
var arr2New = unique(arr2).sort();
$.each(arr2New, function (i, val) {
$("<input/>", {
"type": "checkbox",
"class": "chk",
"data-class": "loc",
"data-value": val,
"id": "chk" + val,
"checked": "checked"
}).appendTo("#" + idOfHolderDiv).wrap("<div></div>").after(val);
});
$("#" + idOfHolderDiv).append("<hr>");
function unique(array) {
return $.grep(array, function (el, index) {
return index == $.inArray(el, array);
});
}
}
// STEP ONE ENDS
///STEP TWO
// On any checkbox clicked returns desired out
var selectedSalaryArr = [];
var selectedLocationArr = [];
$("body").on('change', '.chk', function () {
var selectedVal = $(this).attr('data-value');
$('#filterDiv div').each(function () {
var checkedval = $(this).find('input.chk').attr('data-value');
var isChecked = $(this).find('input.chk').is(':checked');
var dataClass = $(this).find('input.chk').attr('data-class');
if (selectedVal === checkedval) {
if (dataClass === 'sal') {
var isExists = $.inArray(checkedval, selectedSalaryArr);
if (isExists === -1) {
selectedSalaryArr.push(checkedval);
} else {
selectedSalaryArr.splice($.inArray(checkedval, selectedSalaryArr), 1);
}
} else {
var isExists = $.inArray(checkedval, selectedLocationArr);
if (isExists === -1) {
selectedLocationArr.push(checkedval);
} else {
selectedLocationArr.splice($.inArray(checkedval, selectedLocationArr), 1);
}
}
}
});
$('#myTable tbody tr').each(function () {
var currentSalary = $(this).find('.sal').text();
var currentLocation = $(this).find('.loc').text();
var matchedSalaryValueExists = $.inArray(currentSalary, selectedSalaryArr);
var matchedLocationValueExists = $.inArray(currentLocation, selectedLocationArr);
if (selectedSalaryArr.length > 0 && selectedLocationArr.length > 0) {
if (matchedSalaryValueExists !== -1 && matchedLocationValueExists !== -1) {
if (!($(this).hasClass('hiderow'))) {
$(this).addClass('hiderow');
}
} else {
if ($(this).hasClass('hiderow')) {
$(this).removeClass('hiderow');
$(this).show();
}
}
}
else {
if (matchedSalaryValueExists !== -1 || matchedLocationValueExists !== -1) {
if (!($(this).hasClass('hiderow'))) {
$(this).addClass('hiderow');
}
} else {
if ($(this).hasClass('hiderow')) {
$(this).removeClass('hiderow');
$(this).show();
}
}
}
});
$('#myTable tbody tr.hiderow').hide();
});
});
Below is the jsfiddle link:
https://jsfiddle.net/shrawanlakhe/v8gyde77/

Call an object method from html in javascript

I wrote a class for simple booking system. Data is kept in an array and all the edit and delete operations are performed to this array using functions inside that class. So placed buttons to perform edit and delete. How can I call a method from my class to the onclick event of a button. Please check the following code.
Class file
/**
* Class for handling general insert, update, delete
* oprations for a room booking system.
*/
var bookingSystem = function (){
this.editMode = false;
this.editIndex = false;
// option data for Number of persons drop down
this.numPersonsOpts = [
{name : 1, val : 1},
{name : 2, val : 2},
{name : 3, val : 3},
{name : 4, val : 4}
];
// Sample data to show initially
this.bookingData = [
{name : "John", roomType : "AC", numPersons : 3},
{name : "Mishal", roomType : "Non AC", numPersons : 1}
];
var self = this; // get a reference to this.
/**
* Prepare and show options for dropdown
* #param string selectorId id of the dropdown
* #param object optionData array object contains name and value for the options
*/
this.showOptions = function (selectorId, optionData){
var optsStr = "";
for (var i=0; i<optionData.length; i++) {
optsStr += '<option value='+optionData[i].val+'>'+optionData[i].name+'</option>';
};
document.getElementById(selectorId).innerHTML = optsStr;
}
/**
* To save and update data
*/
this.saveBooking = function (){
var name = document.getElementById("bookingName").value;
if(name){
var singleEntry = {
name : name,
roomType : document.querySelector('input[name="roomType"]:checked').value == 1? 'AC' : 'Non AC',
numPersons : document.getElementById("numPersonSelect").value
}
if(self.editMode){
if(typeof(self.editIndex) == 'number'){
self.bookingData[self.editIndex] = singleEntry;
self.editIndex = false;
}
self.editMode = false;
}else{
self.bookingData.push(singleEntry);
}
document.getElementById("bookingName").value = '';
self.renderTemplate();
}
}
/**
* To edit a particular item
* #param number index array index to edit
*/
self.edit = function (index){
self.editIndex = index;
self.editMode = true;
document.getElementById("bookingName").value = self.bookingData[self.editIndex].name;
document.querySelector('input[name="roomType"][value="1"]').checked = self.bookingData[self.editIndex].roomType == 'AC'? true: false;
document.querySelector('input[name="roomType"][value="2"]').checked = self.bookingData[self.editIndex].roomType == 'Non AC'? true: false;
for(var i=0; i<this.numPersonsOpts.length; i++){
document.getElementById("numPersonSelect").options[i].selected = false;
}
document.getElementById("numPersonSelect").options[(self.bookingData[self.editIndex].numPersons)-1].selected = true;
}
/**
* To delete a particular item
* #param number index array index to delete
*/
self.deleteItem = function (index){
self.bookingData.splice(index,1);
self.renderTemplate();
}
/**
* To preapre table content and show it.
*/
this.renderTemplate = function (){
var template = '';
if(self.bookingData.length > 0){
for(var i= 0; i< self.bookingData.length; i++){
template += '<tr>';
template += '<td>'+self.bookingData[i].name+'</td>';
template += '<td>'+self.bookingData[i].roomType+'</td>';
template += '<td>'+self.bookingData[i].numPersons+'</td>';
template += '<td><button type="button" onclick = "edit('+i+')">Edit</button></td>';
template += '<td><button type="button" onclick = "deleteItem('+i+')">Delete</button></td>';
template += '</tr>';
}
}else{
template += '<tr>';
template += '<td colspan="2"> No Data Found.</td>';
template += '</tr>';
}
document.getElementById("renderTable").innerHTML = template;
}
}
General code for initializing it.
var bs = new bookingSystem(); // Create object for bookingSystem
var init= function(){
bs.showOptions('numPersonSelect',bs.numPersonsOpts); // Show number of persons option
// Save Button event
var btn = document.getElementById("saveBookingBtn");
if(btn.addEventListener){
btn.addEventListener('click',bs.saveBooking);
}else{
btn.attachEvent('onclick',bs.saveBooking);
}
bs.renderTemplate();
}
function edit(index){
bs.edit(index);
}
function deleteItem(index){
bs.deleteItem(index);
}
init() is called from body onload event. Following is the html code.
<body onload="init()">
<form>
<div class="formRow">
<label>Name : </label>
<input type="text" id="bookingName" name="bookingName" value="">
</div>
<div class="formRow">
<label>AC/NO : </label>
<input type="radio" value="1" name="roomType" checked="checked"> AC
<input type="radio" value="2" name="roomType"> Non AC
</div>
<div class="formRow">
<label>Number of Persons</label>
<select name="numPerson" id="numPersonSelect">
</select>
</div>
<div>
<button type="button" id="saveBookingBtn">Save</button>
</div>
</form>
<div id="renderArea"></div>
<table>
<td>Name</td>
<td>Room Type</td>
<td>Person(s)</td>
<td>Edit</td>
<td>Delete</td>
<tbody id="renderTable"></tbody>
</table>
</body>
This code is working fine. But here I created edit and deleteItem methods to call the actual edit and delete methods wrote in the class. How to use that methods from class directly to onclick event. Like this <button onclick="bs.edit()">Edit</button>
$(function(){
var productManagement = function() {
var products = [
{id:1, name: 'samsung galaxy', price: 6000, description: 'samsung galaxy mobile phone'},
{id:2, name: 'apple', price: 10000, description: 'apple mobile phone'},
{id:3, name: 'nokia', price: 5000, description: 'nokia mobile phone'},
{id:4, name: 'motorola', price: 7000, description: 'motorola mobile phone'}
];
var selectedProducts = {};
var $this = this;
this.displayProducts = function() {
$.each(products, function(k, product){
$('.content').append($this.getProductInfo(product));
});
}
this.getProductInfo = function(product) {
var html = '<div class="item" id="' + product.id + '">';
html += '<table><tr><td>Name</td><td>: ' + product.name + '</td></tr>';
html += '<tr><td>Price</td><td>: ' + product.price + '</td></tr>';
html += '<tr><td>Description</td><td>: ' + product.description + '</td></tr>';
html += '<tr><td colspan="2"><button class="addToCart">Add To Cart</td></tr></table>'
html += '</div>';
return html;
}
this.delegate = function() {
$('body').delegate('.addToCart', 'click', function(){
var id = $(this).closest('div').attr('id');
if( selectedProducts[id] == undefined) {
selectedProducts[id] = 1;
}else{
selectedProducts[id]++;
}
// selectedProducts.push(id);
$('.content').hide();
$('.cart').show();
$this.showCart();
});
$('body').delegate('#continueShopping', 'click', function(){
$('.content').show();
$('.cart').hide();
});
$('body').delegate('.remove', 'click', function(){
var id = $(this).closest('tr').attr('id');
$this.removeFromSelected(id);
});
}
this.removeFromSelected = function(productId){
$.each(selectedProducts, function(pid, numberOfItems){
if( pid == productId) {
delete selectedProducts[pid];
return false;
}
});
$this.showCart();
}
this.showCart = function() {
var html = '<table><tr><th>Name</th><th>Unit Price</th><th>No of Items</th><th>Total Price</th><th>Action</th></tr>';
var total = 0;
$.each(selectedProducts, function(productId,numberOfItems){
var productInfo = $this.getProduct(productId);
html += '<tr id="' + productId + '"><td>' + productInfo.name + '</td><td>' + (productInfo.price) + '</td><td>'+ numberOfItems + '</td><td>' + (productInfo.price * numberOfItems) + '</td><td><button class="remove">Remove</button></td></tr>';
total += productInfo.price;
});
html += '</table>';
html += '<br /><br />Grand Total:' + total;
$('#cartItems').empty();
$('#cartItems').append(html);
}
this.getProduct = function(productId) {
var found = {};
$.each( products, function(id, product){
if( product.id == productId) {
found = product;
return false;
}
})
return found;
}
}
var PM = new productManagement();
PM.delegate();
PM.displayProducts();
})
.header {
background-color:#E0E8FF;
padding:5px;
text-align:center;
}
.content {
padding-left:15%;
padding-top:40px;
width:100%;
overflow:auto
}
.cart {
padding-left:15%;
padding-top:40px;
width:100%;
}
.footer {
background-color:#E0E8FF;
text-align:center;
}
.item {
width:25%;
height:150px;
overflow:auto;
border:1px solid black;
float:left
}
The function which you are calling is not exist in the context for delete when document loaded. By defining the function as global function, it is working.
/**
* Class for handling general insert, update, delete
* oprations for a room booking system.
*/
var bookingSystem = function (){
this.editMode = false;
this.editIndex = false;
// option data for Number of persons drop down
this.numPersonsOpts = [
{name : 1, val : 1},
{name : 2, val : 2},
{name : 3, val : 3},
{name : 4, val : 4}
];
// Sample data to show initially
this.bookingData = [
{name : "John", roomType : "AC", numPersons : 3},
{name : "Mishal", roomType : "Non AC", numPersons : 1}
];
var self = this; // get a reference to this.
/**
* Prepare and show options for dropdown
* #param string selectorId id of the dropdown
* #param object optionData array object contains name and value for the options
*/
this.showOptions = function (selectorId, optionData){
var optsStr = "";
for (var i=0; i<optionData.length; i++) {
optsStr += '<option value='+optionData[i].val+'>'+optionData[i].name+'</option>';
};
document.getElementById(selectorId).innerHTML = optsStr;
}
/**
* To save and update data
*/
this.saveBooking = function (){
var name = document.getElementById("bookingName").value;
if(name){
var singleEntry = {
name : name,
roomType : document.querySelector('input[name="roomType"]:checked').value == 1? 'AC' : 'Non AC',
numPersons : document.getElementById("numPersonSelect").value
}
if(self.editMode){
if(typeof(self.editIndex) == 'number'){
self.bookingData[self.editIndex] = singleEntry;
self.editIndex = false;
}
self.editMode = false;
}else{
self.bookingData.push(singleEntry);
}
document.getElementById("bookingName").value = '';
self.renderTemplate();
}
}
/**
* To edit a particular item
* #param number index array index to edit
*/
self.edit = function (index){
self.editIndex = index;
self.editMode = true;
document.getElementById("bookingName").value = self.bookingData[self.editIndex].name;
document.querySelector('input[name="roomType"][value="1"]').checked = self.bookingData[self.editIndex].roomType == 'AC'? true: false;
document.querySelector('input[name="roomType"][value="2"]').checked = self.bookingData[self.editIndex].roomType == 'Non AC'? true: false;
for(var i=0; i<this.numPersonsOpts.length; i++){
document.getElementById("numPersonSelect").options[i].selected = false;
}
document.getElementById("numPersonSelect").options[(self.bookingData[self.editIndex].numPersons)-1].selected = true;
}
/**
* To delete a particular item
* #param number index array index to delete
*/
self.deleteItem = function (index){
console.log("called once");
self.bookingData.splice(index,1);
self.renderTemplate();
}
/**
* To preapre table content and show it.
*/
this.renderTemplate = function (){
var template = '';
if(self.bookingData.length > 0){
for(var i= 0; i< self.bookingData.length; i++){
template += '<tr>';
template += '<td>'+self.bookingData[i].name+'</td>';
template += '<td>'+self.bookingData[i].roomType+'</td>';
template += '<td>'+self.bookingData[i].numPersons+'</td>';
template += '<td><button type="button" onclick = "return callEdit('+i+')">Edit</button></td>';
template += '<td><button type="button" onclick = "return callDelete('+i+')">Delete</button></td>';
template += '</tr>';
}
}else{
template += '<tr>';
template += '<td colspan="2"> No Data Found.</td>';
template += '</tr>';
}
document.getElementById("renderTable").innerHTML = template;
}
this.init= function(){
console.log("called");
self.showOptions('numPersonSelect',self.numPersonsOpts); // Show number of persons option
// Save Button event
var btn = document.getElementById("saveBookingBtn");
if(btn.addEventListener){
btn.addEventListener('click',self.saveBooking);
}else{
btn.attachEvent('onclick',self.saveBooking);
}
self.renderTemplate();
}
}
var bs = new bookingSystem(); // Create object for bookingSystem
bs.init();
window.callEdit = function(index){
bs.edit(index);
}
window.callDelete = function(index){
bs.deleteItem(index);
}
check this example here

How to give Input tag attribute type button value at Runtime in Meteor JS

How to give Input tag Attribute type button value at Runtime in Meteor JS as shown below:
newButton = document.createElement('input');
newButton.value = ''; - Here value i need like as i.e , val ="{{btnValue}}"
I'm not familiar with Meteor JS, so please offer any suggestions.
Html Code I need like as below in Runtime JS:
// Manually Creating button
<input type="button" id="no" val ="{{btnValue}}">
My HTML Code :
<head>
<title>TICTACTOE App 1.3</title>
</head>
<body>
{{> uname}}
{{> main}}
{{> games }}
</body>
<template name="uname">
<h1>Welcome to TICTACTOE App</h1>
<p id="pname"><b>User Name :</b> <input type="text" id="uname" ></p>
</template>
<template name="main">
<p id="pno"><b>Layout Number :</b> <input type="text" id="no" ></p>
<div name="main"></div>
</template>
<template name="games">
{{#each game}}
<div>{{turn}} </div>
<div> {{wturn}}</div>
<div>{{bval}}</div>
{{/each}}
</template>
Meteor JS:
Counts = new Meteor.Collection('count');
TurnData= new Meteor.Collection('tdata');
BtnValues= new Meteor.Collection('btnvalues');
var x = "X";
var o = "O";
var Whoseturn = "";
var no;
var newButton;
var count = 0;
var IsWin = false;
var IsTurn = true;
var val = "";
var ButtonValue= "";
var btnval;
if (Meteor.isClient)
{
Template.main.helpers
({
btnValue: function()
{
return BtnValues.findOne();
}
});
Template.main.events
({
'click input' : function ()
{
// template data, if any, is available in 'this'
var name = document.getElementById('uname');
console.log(name.value);
var btnid = event.currentTarget.id;
ButtonValue = btnid;
btnval = document.getElementById(btnid);
console.log(btnid);
if(btnval.value == '' && btnid != "no" )
{
calculateTurn();
console.log(Whoseturn);
btnval.value = Whoseturn;
var myBtnData = BtnValues.findOne();
BtnValues.update( {_id: myBtnData._id},{ $set:{bval : btnval} });
}
}
});
Template.main.events
({
'keydown input#no' : function ()
{
// template data, if any, is available in 'this'
if (event.which == 13)
{
// 13 is the enter key event
console.log("You pressed enter key");
no = document.getElementById('no');
count = 0;
var myTurnData = Counts.findOne();
Counts.update( {_id: myTurnData._id},{ $set:{turn : count } });
if(no.value != '')
{
document.getElementById('pname').style.visibility = 'hidden';
document.getElementById('pno').style.visibility = 'hidden';
UI();
}
}
}
});
}
function UI()
{
console.log("*** UI() ***");
for(var i = 1 ; i <= no.value ; i++)
{
//var body=document.getElementsByTagName('body')[0];
var body = document.getElementsByName('main')[0];
for(var j = 1 ; j <= no.value ; j++)
{
newButton = document.createElement('input');
newButton.type = 'button';
newButton.id = 'btn'+i+j;
newButton.value = '';////Here value i need like as val ="{{btnValue}}
body.appendChild(newButton);
}
var newline = document.createElement('br');
body.appendChild(newline) ;
}
}
function calculateTurn()
{
var myTurnData = Counts.findOne();
count = myTurnData.turn;
console.log("count="+count);
count = count + 1;
console.log("updated count="+count);
Counts.update( {_id: myTurnData._id},{ $set:{turn : count } });
if(count <= 9)
{
var TData = TurnData.findOne();
IsTurn = true;
if(count % 2 == 0)
{
Whoseturn = o ;
TurnData.update( {_id: TData._id},{ $set:{wturn : Whoseturn } });
}
else
{
Whoseturn = x ;
TurnData.update( {_id: TData._id},{ $set:{wturn : Whoseturn } });
}
}
else
{
IsTurn = false;
console.log(" >= 9");
}
}
if (Meteor.isServer)
{
Meteor.startup(function ()
{
// code to run on server at startup
Counts.insert({turn : count});
TurnData.insert({wturn : Whoseturn});
BtnValues.insert({bval : val});
});
}

Categories