How to combine these functions without repeating? - javascript

As all the 3 product functions has the same product list how can i combine these multiple functions into one so that i can avoid repeating myself here.
How to combine these three functions into one as all the functions has the product list only the currency are different? Could someone please suggest me. Thanks
function ProductDataRenderer() { }
ProductDataRenderer.prototype.render = function () {
var nzd =
'<table class="table table-striped">'
+' <thead>'
+' <tr><td colspan="3">Products (NZD)</td></tr>'
+' <tr>'
+' <td>Name</td>'
+' <td>Price</td>'
+' <td>Type</td>'
+' </tr>'
+' </thead>'
+ ' <tbody>';
var n = ProductDataConsolidator.get();
for (var i = 0; i < n.length; i++) {
nzd +=
'<tr>'
+ '<td>' + n[i].name +'</td>'
+ '<td>' + n[i].price + '</td>'
+ '<td>' + n[i].type + '</td>'
+ '</tr>';
}
nzd += '</tbody></table>';
document.getElementById("nzdProducts").innerHTML = nzd;
var usd =
'<table class="table table-striped">'
+ ' <thead>'
+ ' <tr><td colspan="3">Products (USD)</td></tr>'
+ ' <tr>'
+ ' <td>Name</td>'
+ ' <td>Price</td>'
+ ' <td>Type</td>'
+ ' </tr>'
+ ' </thead>'
+ ' <tbody>';
var u = ProductDataConsolidator.getInUSDollars();
for (var i = 0; i < u.length; i++) {
usd +=
'<tr>'
+ '<td>' + u[i].name + '</td>'
+ '<td>' + u[i].price + '</td>'
+ '<td>' + u[i].type + '</td>'
+ '</tr>';
}
usd += '</tbody></table>';
document.getElementById("usdProducts").innerHTML = usd;
var euro =
'<table class="table table-striped">'
+ ' <thead>'
+ ' <tr><td colspan="3">Products (Euro)</td></tr>'
+ ' <tr>'
+ ' <td>Name</td>'
+ ' <td>Price</td>'
+ ' <td>Type</td>'
+ ' </tr>'
+ ' </thead>'
+ ' <tbody>';
var e = ProductDataConsolidator.getInEuros();
for (var i = 0; i < e.length; i++) {
euro +=
'<tr>'
+ '<td>' + e[i].name + '</td>'
+ '<td>' + e[i].price + '</td>'
+ '<td>' + e[i].type + '</td>'
+ '</tr>';
}
euro += '</tbody></table>';
document.getElementById("euProducts").innerHTML = euro;
}

Hey this one should do the trick
const renderTable = ({ items, title, containerId }) => {
let tableTemplate =
'<table class="table table-striped">' +
' <thead>' +
` <tr><td colspan="3">${title}</td></tr>` +
' <tr>' +
' <td>Name</td>' +
' <td>Price</td>' +
' <td>Type</td>' +
' </tr>' +
' </thead>' +
' <tbody>'
for (let i = 0; i < items.length; i++) {
tableTemplate +=
'<tr>' +
`<td>${items[i].name}</td>` +
`<td>${items[i].price}</td>` +
`<td>${items[i].type}</td>` +
`</tr>`
}
tableTemplate += '</tbody></table>'
document.getElementById(containerId).innerHTML = tableTemplate
}
renderTable({
items: ProductDataConsolidator.get(),
title: 'Products (NZD)',
containerId: 'nzdProducts'
})
renderTable({
items: ProductDataConsolidator.getInUSDollars(),
title: 'Products (USD)',
containerId: 'usdProducts'
})
renderTable({
items: ProductDataConsolidator.getInEuros(),
title: 'Products (Euro)',
containerId: 'euProducts'
})

Related

How to combine multiple functions into one without repeating?

In the ProdRender.js I wanna combine those three functions into one so that i do not repeat and that should match to ProdData.js as the data is in the ProdData.js and its rendering through ProdRender.js
Could someone please suggest me how to do it without repeating anything in the prodRender.js The ProdData.js seems to be working fine as i'm not repeating anything only the prodRender.js is where i'm repeating thrice.
So please help me out here
Thanks
//ProdRender.js
function ProductDataRenderer() { }
ProductDataRenderer.prototype.render = function () {
var nzd =
'<table class="table table-striped">'
+' <thead>'
+' <tr><td colspan="3">Products (NZD)</td></tr>'
+' <tr>'
+' <td>Name</td>'
+' <td>Price</td>'
+' <td>Type</td>'
+' </tr>'
+' </thead>'
+ ' <tbody>';
var n = ProductDataConsolidator.get();
for (var i = 0; i < n.length; i++) {
nzd +=
'<tr>'
+ '<td>' + n[i].name +'</td>'
+ '<td>' + n[i].price + '</td>'
+ '<td>' + n[i].type + '</td>'
+ '</tr>';
}
nzd += '</tbody></table>';
document.getElementById("nzdProducts").innerHTML = nzd;
var usd =
'<table class="table table-striped">'
+ ' <thead>'
+ ' <tr><td colspan="3">Products (USD)</td></tr>'
+ ' <tr>'
+ ' <td>Name</td>'
+ ' <td>Price</td>'
+ ' <td>Type</td>'
+ ' </tr>'
+ ' </thead>'
+ ' <tbody>';
var u = ProductDataConsolidator.getInUSDollars();
for (var i = 0; i < u.length; i++) {
usd +=
'<tr>'
+ '<td>' + u[i].name + '</td>'
+ '<td>' + u[i].price + '</td>'
+ '<td>' + u[i].type + '</td>'
+ '</tr>';
}
usd += '</tbody></table>';
document.getElementById("usdProducts").innerHTML = usd;
var euro =
'<table class="table table-striped">'
+ ' <thead>'
+ ' <tr><td colspan="3">Products (Euro)</td></tr>'
+ ' <tr>'
+ ' <td>Name</td>'
+ ' <td>Price</td>'
+ ' <td>Type</td>'
+ ' </tr>'
+ ' </thead>'
+ ' <tbody>';
var e = ProductDataConsolidator.getInEuros();
for (var i = 0; i < e.length; i++) {
euro +=
'<tr>'
+ '<td>' + e[i].name + '</td>'
+ '<td>' + e[i].price + '</td>'
+ '<td>' + e[i].type + '</td>'
+ '</tr>';
}
euro += '</tbody></table>';
document.getElementById("euProducts").innerHTML = euro;
}
//ProdData.js
function ProductDataConsolidator() { }
ProductDataConsolidator.get = function (currency) {
var l = new LawnmowerRepository().getAll();
var p = new PhoneCaseRepository().getAll();
var t = new TShirtRepository().getAll();
const arr_names = [
[l, "lawnmower"],
[p, "Phone Case"],
[t, "T-Shirt"],
]
var products = [];
let multiplier = currency == "euro"
? 0.67
: currency == "dollar"
? 0.76
: 1;
for (let [arr,name] of arr_names){
for (var i = 0; i < arr.length; i++) {
products.push({
id: arr[i].id,
name: arr[i].name,
price: (arr[i].price * multiplier).toFixed(2),
type: name
});
}
}
return products;
}
ProductDataConsolidator.getInEuros = function(){
return ProductDataConsolidator.get("euro");
}
ProductDataConsolidator.getInUSDollars = function(){
return ProductDataConsolidator.get("dollar");
}
You need to break it down to smaller functions and parameterise them
const table = (currency, content) =>
`<table class="table table-striped">
<thead>
<tr><td colspan="3">Products (${currency})</td></tr>
<tr>
<td>Name</td>
<td>Price</td>
<td>Type</td>
</tr>
</thead>
<tbody>
${content}
</tbody>
</table>`
;
const table_content = data =>
data.map(({ name, price, type }) =>
`<tr>
<td>${name}</td>
<td>${price}</td>
<td>${type}</td>
</tr>`)
.join('\n')
;
const currencyCode = {
dollar: 'USD',
euro: 'Euro',
newZealand: 'NZD'
};
function ProductDataRenderer() { }
ProductDataRenderer.prototype.render = function (currency, target) {
const productData = ProductDataConsolidator.get(currency);
const html = table(currencyCode[currency], table_content(productData));
document.getElementById(target).innerHTML = html;
}
I didn't change the design of your code but you can see render does 3 different things. It should only render, not also retrieve data and inject the table in the DOM.
It makes also little sense to have one ProductDataConsolidator with three static methods having different names. Either you create 3 derivatives of ProductDataConsolidator with only one method get each and you pass an instance of the right derivative to render so that it only needs to know about one method named get (by the way if you have one object with only one method it's a function so why bother use an object), or you pass the product data directly to render (preferred)

Seeking help on syntax error with js string concatenation

I'm trying to toggle between the innerHTML of a table data cell from an AJAX output from onclick row event:
JS:
...
var thisrownumber = 0;
var detailednote = '';
var simplifiednote = '';
htmlStr += '<table>';
$.each(data, function(k, v){
thisrownumber ++;
detailednote = v.note_ids;
simplifiednote = '<img class="See" src="~.png" alt="See" style="width:20px; height:20px;"> See';
htmlStr += '<tr onclick="shrow(' + thisrownumber + ',' + detailednote + ',' + simplifiednote + ')">'
+ '<td>' + v.date + '</td>'
+ '<td>' + v.r + '</td>'
+ '<td>' + v.f + ': ' + v.s + '</td>'
+ '<td>' + '<span id="span_note' + thisrownumber + '">' + simplifiednote + '</span>'
+ '</td>'
+ '</tr>';
});
htmlStr += '</table>';
$("#content").html(htmlStr);
} // function close
function shrow(x,y,z){
var lang3 = "span_note";
var shrow = x;
var span_note = lang3.concat(x);
if(document.getElementById(span_note).innerHTML == y){
document.getElementById(span_note).innerHTML = z;
}
if(document.getElementById(span_note).innerHTML == z){
document.getElementById(span_note).innerHTML = y;
}
}
HTML:
<div id="content"></div>
Getting error:
Uncaught SyntaxError: missing ) after argument list

Cannot read property 'length' of undefined error in DataTable.js

I have read all the previous threads concerning this topic, but still end up getting
Uncaught TypeError: Cannot read property 'length' of undefined
in both Chrome and Internet Explorer. I have created an empty file, named it "DataTable.js" and copy-pasted the code from here
Then I added the following line at the end of the code where my table is built:
$('#standard_report_table').DataTable();
My scripts:
var buildStandardReportTable = function()
{
var divContent = "";
var url = "/InputData/db_getSqlQueryResult";
$.ajax({
url: url,
type: "POST",
async: false,
data: { sqlStr: "SELECT id, name_rus, visual_level, children_number, parent_id, effect_on_parent_id, lft, rgt, children_are_visible, report_type_id, font_color " +
"FROM report_entries_template_standard " +
"WHERE visible = 1 AND report_type_id = " + $("#reportTypeCombobox").val() + ' ' +
"ORDER BY lft", connectionStr: "dbCon"},
success: function (data)
{
var divContent = '';
var obj = jQuery.parseJSON(data);
divContent = buildStandarReportContent(obj);
//$('#choosenav1')[0].style.display = "block";
//$('#choosenav2')[0].style.display = "block";
//$('#choosenav3')[0].style.display = "block";
$("#standard_report_table").html(divContent);
$('#standard_report_table').DataTable();
}
})
}
var buildStandarReportContent = function (obj)
{
var divContent = '<thead border="0"><tr>';
divContent += '<th style="width: 30px"></th>';
divContent += '<th style="width: 30px"></th>';
divContent += '<th style="width: 30px"></th>';
divContent += '<th style="width: 30px"></th>';
divContent += '<th style="width: 30px"></th>';
divContent += '<th style="width: 30px"></th>';
divContent += '<th style="width: 30px"></th>';
divContent += '<th style="width: 1000px;">Статья</th>';
divContent += '<th>ID</th>';
divContent += '</tr></thead>';
// Table content
divContent += '<tbody id="table_data">';
for (i = 0; i < obj.length; i++)
{
//'<tr class="' + (obj[i].Уровень == 1 ? "success" : "")
//+ (obj[i].Уровень == 2 ? "warning" : "") + '"><td style="vertical-align: middle"><div style="margin-left:' + (obj[i].Уровень - 1) * 20 + 'px">' + obj[i].Статья_название + '</div></td>';
divContent += '<tr style="height: 10px; background-color:' + obj[i].font_color + '" ' +
'onmouseover = "setElementsVisibility(' + i + ', 1)" ' +
'onmouseout = "setElementsVisibility(' + i + ', 0)">';
divContent += '<td><div id = "add_child_sign' + i + '" style = "display : none";"><img src= "/Content/pics/plus_sign1.png" ' +
'style= "height:10px;width:10px;cursor:pointer" ' +
'onclick = "openAddNewChildWindow(' + obj[i].id + ')"</div></td>';
divContent += '<td><div id = "delete_sign' + i + '" style = "display : none";"><img src= "/Content/pics/delete_sign1.png" ' +
'style= "height:10px;width:10px;cursor:pointer" ' +
'onclick = "deleteChild(' + obj[i].id + ')"</div></td>';
divContent += '<td><div class = "glyphicon glyphicon-triangle-top" varia-hidden="true" id = "arrowup' + i + '" style = "' +
'height:10px;width:10px;cursor:pointer; color:red" ' +
'onclick = "swapChild(' + obj[i].id + ', \'up\')"></div>';
divContent += '<td><div class = "glyphicon glyphicon-triangle-bottom" id = "arrowdown' + i + '" style = " ' +
'height:10px; width:10px; cursor:pointer" ' +
'onclick = "swapChild(' + obj[i].id + ', \'down\')"></div></td>';
divContent += '<td><div id = "arrowleft' + i + '" style = "display : none";"><img src= "/Content/pics/arrowleft_sign1.png" ' +
'style= "height:10px;width:10px;cursor:pointer" ' +
'onclick = "editVisualLevel(' + obj[i].id + ', \'left\')"</div></td>';
divContent += '<td><div id = "arrowright' + i + '" style = "display : none";"><img src= "/Content/pics/arrowright_sign1.png" ' +
'style= "height:10px;width:10px;cursor:pointer" ' +
'onclick = "editVisualLevel(' + obj[i].id + ', \'right\')"</div></td>';
divContent += '<td><div id = "edit_sign' + i + '" style="display: none;"><div style = "vertical-align:bottom"><img src= "/Content/pics/edit_sign1.png" ' +
'style= "height:10px;width:10px;cursor:pointer" ' +
'onclick = "openEditChildWindow(' +
obj[i].id + ',\'' + obj[i].name_rus + '\',\'' + obj[i].name + '\',' + obj[i].effect_on_parent_id + ',' +
obj[i].parent_id + ',' + obj[i].report_type_id + ')"</div></td>';
divContent += '<td><div class = "cell_level_' + obj[i].visual_level + '" style = "margin-left : ' + 30 * (obj[i].visual_level - 1) + 'px; ' +
'cursor:' + (obj[i].children_number == 0 ? "default" : "pointer") + '" ' +
'onclick="collapseTreeNode(' + obj[i].lft + ',' + obj[i].rgt + ',' + obj[i].children_are_visible + ','+ obj[i].children_number + ')">';
divContent += obj[i].name_rus + '<span style="color:#A0A0A0; font-weight: normal;">&nbsp(' + obj[i].children_number + ')</span></div></td><td>' + obj[i].id + '</td><tr>';
}
divContent += '</tbody>'
divContent += '</table>';
return divContent;
}
HTML:
<div class="container">
<table id="standard_report_table" class="table table-striped"></table>
</div>
Use in this way.
var obj = jQuery.parseJSON(data);
$('#standard_report_table').DataTable({
"ajax": obj
});
define html
<table id="standard_report_table" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
</table>

Can't get value from table td with quotes

Here I am creating dynamic table
function addToMLContainer(id, mlName, mlAddress) {
return '<td><s:text>' + mlName + ' ' + mlAddress + '</s:text></td>' +
'<td hidden="hidden">' + id + '<input name="mlId" type="hidden" value = "' + id + '" /></td>' +
'<td hidden="hidden"><input name="mlFullName" type="hidden" value = "' + mlName + ' ' + mlAddress + '" /></td>' +
'<td align="center"><img src="/delete.png" class="remove" onclick="this.closest(\'tr\').remove()"/></td>'
}
And here I am getting value of tr:
var t = document.getElementById("AddedMlsContainer");
for (var i = 1, row; row = t.rows[i]; i++) {
selectedMerchants = selectedMerchants + " " + row.cells[2].children[0].value + "\n";
}
The problem is I can't get value with double or single quotes like <I'm "blabla">
Finally I did it by removing input field and unnesessary td:
'<td>' + mlName + ' ' + mlAddress + '</td>' +
'<td hidden="hidden">' + id + '<input name="mlId" type="hidden" value = "' + id + '" /></td>' +
'<td align="center"><img src="/delete.png" class="remove" onclick="this.closest(\'tr\').remove()"/></td>'
Then I used innerHtml
var t = document.getElementById("AddedMlsContainer");
for (var i = 1, row; row = t.rows[i]; i++) {
selectedMerchants = selectedMerchants + " " + row.cells[0].innerHTML.replace(/ /g,'') + "\n";
}

Set the td color for each types in extjs

I want the each request type must be displayed in different color based on CSS class name.
code:
mcmShowTaskMessageBox: function(task, menu) {
var message = '<table class="eventTipBig">';
var requestType = task.get('RequestType');
var alert = task.get('Alerts');
if(requestType === 'OA VIP') {
menu.tdCls = 'OAVIP';
} else if(requestType === 'JL VIP') {
menu.tdCls = 'JLVIP';
} else if(requestType === 'BA VIP') {
menu.tdCls = 'BAVIP';
} else if(requestType === 'IB VIP') {
menu.tdCls = 'IBVIP';
} else if(requestType === 'QF VIP') {
menu.tdCls = 'QFVIP';
}
message +=
'<tr>' +
'<td class="icon-task">Name</td>' +
'<td class="value">' + task.get('Name') + '</td>' +
'</tr>' +
'<tr>' +
'<td class="icon-task">Ranking</td>' +
'<td class="value" style="color:red;">' + PriorityGreet + '</td>' +
'</tr>' +
'<tr>' +
'<td class="icon-task">Request Type</td>' +
'<td class="value">' + requestType + '</td>' +
'</tr>' +
'<tr>' +
'<td class="icon-task">Agent</td>' +
'<td class="value">' + task.get('AgentName') + '</td>' +
'</tr>' +
'<tr>' +
'<td class="icon-task">Service Type</td>' +
'<td class="value">' + task.get('TaskType') + '</td>' +
'</tr>' +
'<tr>' +
'<td class="icon-task">Task Status</td>' +
'<td class="value">' + task.get('TaskStatus') + '</td>' +
'</tr>' +
'<tr>' +
'<td class="icon-task">Task Category</td>' +
'<td class="value">' + task.get('TaskCategory') + '</td>' +
'</tr>'+
'<tr>' +
'<td class="icon-task">Notes</td>' +
'<td class="value">' + task.get('Notes') + '</tr>' +
'</tr>' +
'</table>';
App.mcmShowMessageBox({
id: 'TaskGrid' + task.get('Id'),
title: 'Task Information',
message: message,
editOption: { task: task, menu: menu }
});
//modification ended
}

Categories