I'm working with a list of HTML headers (h2,h3,h4,h5,h6).
The picture describes the idea:
[
{
text: 'Some header',
rank: 2, // stays for <h2>
},
{
text: 'Some another header',
rank: 3, // stays for <h3>
},
{
text: 'A header with the same rank',
rank: 3, // stays for <h3>
},
{
text: 'One more subsection header',
rank: 4, // stays for <h4>
}
]
And I'm trying to turn it into a tree:
[
{
text: 'Some header',
children: [
{
text: 'Some another header',
},
{
text: 'A header with the same rank',
children: [
{
text: 'One more subsection header',
}
]
}
]
}
]
Here's my current code:
function list_to_tree(list) {
// We go from the end to the beggining
list = list.reverse();
let node, nextNode, roots = [], i;
for (i = 0; i < list.length; i += 1) {
node = list[i];
nextNode = list[i+1];
// If the next one's rank is greater, the current into the next as a child
if (nextNode !== undefined && node.rank > nextNode.rank) {
list[i+1].children.push(node);
} else {
// Else it's a root
roots.push(node);
}
}
return roots;
};
But it works only for the first h3, but the second h3 will go as a root. Any idea on how to achieve the goal? Thank you.
You could use the level property rank for indicating the nested position in a helper array.
Then iterate the data and build children arrays, if necessary.
function getTree(array) {
var levels = [{}];
array.forEach(function (o) {
levels.length = o.rank;
levels[o.rank - 1].children = levels[o.rank - 1].children || [];
levels[o.rank - 1].children.push(o);
levels[o.rank] = o;
});
return levels[0].children;
}
var data = [{ text: 'Main Heading', rank: 1 }, { text: 'Sub Heading', rank: 2 }, { text: 'Sub Sub Heading', rank: 3 }, { text: 'Sub Heading', rank: 2 }, { text: 'Sub Sub Heading', rank: 3 }, { text: 'Sub Sub Heading', rank: 3 }];
console.log(getTree(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
This solution will work irrespective of starting rank and also of the order in which the list is given... and it uses the exact data you provided...
var jsonHeaders =
[
{
text: 'Some header',
rank: 2, // stays for <h2>
},
{
text: 'Some another header',
rank: 3, // stays for <h3>
},
{
text: 'A header with the same rank',
rank: 3, // stays for <h3>
},
{
text: 'One more subsection header',
rank: 4, // stays for <h4>
}
];
function list_to_tree(list)
{
var jsonTree = [{}];
list = list.reverse();
for (i = 0, l = list.length; i < l; i++)
{
node = list[i];
var json = {};
json.text = node.text;
json.rank = node.rank;
if(jsonTree[0].rank == undefined)
{
jsonTree[0] = json;
}
else
if(jsonTree[0].rank == json.rank)
{
jsonTree.push(json);
}
else
if(jsonTree[0].rank < json.rank)
{
jsonTree[0] = ranker(jsonTree[0], json);
}
else
if(jsonTree[0].rank > json.rank)
{
var jsonTemp = jsonTree[0];
jsonTree[0] = json;
json = jsonTemp;
jsonTree[0] = ranker(jsonTree[0], json);
}
}
return jsonTree;
}
function ranker(jsonTree, json)
{
if(jsonTree.children == undefined)
{
jsonTree.children = [];
jsonTree.children.push(json);
}
else
if(jsonTree.children[0].rank == json.rank)
{
jsonTree.children.push(json);
}
else
if(jsonTree.children[0].rank < json.rank)
{
jsonTree.children[0] = ranker(jsonTree.children[0], json);
}
else
if(jsonTree.children[0].rank > json.rank)
{
var jsonTemp = jsonTree;
jsonTree = json;
json = jsonTemp;
jsonTree.children[0] = ranker(jsonTree.children[0], json);
}
return jsonTree;
}
var jsonTree = list_to_tree(jsonHeaders);
console.log('jsonArrayTree = ', jsonTree);
Here's the working function in case someone needs it:
function list_to_tree(list) {
list = list.reverse();
let node, currentRank = list[0].rank, i, roots = [];
for (i = 0; i < list.length; i += 1) {
node = list[i];
if (node.rank > currentRank) {
for (let n = i; n < list.length; n += 1) {
if (list[n].rank < node.rank) {
list[n].children.unshift(node);
break;
}
}
} else {
currentRank = node.rank;
roots.push(node);
}
}
return roots.reverse();
};
I am writing a memory card game. Each time when I refresh the page, the cards are supposed to place in a random position but it turns out that they remain in the same position.
here is the code :
var cardsArray = [{
'name': 'ball',
'img': '../img/ball.png',
},
{
'name': 'building',
'img': '../img/building.png',
},
{
'name': 'fan',
'img': '../img/fan.png',
},
{
'name': 'fish',
'img': '../img/fish.png',
},
{
'name': 'fishball',
'img': '../img/fishball.png',
},
{
'name': 'flower',
'img': '../img/flower.png',
},
{
'name': 'hill',
'img': '../img/hill.png',
},
{
'name': 'orange',
'img': '../img/orange.png',
},
{
'name': 'boo',
'img': '../img/boo.png',
},
{
'name': 'shoe',
'img': '../img/shoe.png',
},
];
var firstGuess = '';
var secondGuess = '';
var count = 0;
var previousTarget = null;
var delay = 1200;
var moves;
var matched;
var score;
var game = document.getElementById('game');
var grid = document.createElement('section');
const gameGrid = cardsArray
.concat(cardsArray)
.sort(function() {
0.5 - Math.random()
});
function startGame() {
grid.setAttribute('class', 'grid');
game.appendChild(grid);
moves = 0;
score = 0;
matched = 0;
document.getElementById("moves").innerHTML = moves;
document.getElementById("score").innerHTML = score;
gameGrid.forEach(function(item) {
const {
name,
img
} = item;
const card = document.createElement('div');
card.classList.add('card');
card.dataset.name = name;
const front = document.createElement('div');
front.classList.add('front');
const back = document.createElement('div');
back.classList.add('back');
back.style.backgroundImage = `url(${img})`;
grid.appendChild(card);
card.appendChild(front);
card.appendChild(back);
});
}
Sorry, I know it might be a bit long, but I guess the problem might be here:
const gameGrid = cardsArray
.concat(cardsArray)
.sort(function() {
0.5 - Math.random()
});
Did I do something wrong here? How can i fix it?
You're not actually returning the random value to sort on.
const gameGrid = cardsArray
.concat(cardsArray)
.sort(function() {
return 0.5 - Math.random()
});
Am having a problem to return match array between two array element, please any help is important
here is my code
$scope.MacA = [
{
name: '24:fd:52:c3:d8:35',
sector: 'A23'
},
{
name: '56:db:30:4b:57:45',
sector: 'It support'
},
{
name: 'b6:b6:76:6b:e9:00',
sector: 'A24'
},
{
name: 'e8:74:e6:a1:14:16',
sector: 'Vodafone Guest'
},
{
name: 'dc:4a:3e:b7:32:0e',
sector: 'Direct HP officejet'
}
,
{
name: '7c:4c:a5:32:13:29',
sector: 'skyb7'
}
]
and array 2 is
scope.match = ['dc:4a:3e:b7:32:0e','7c:4c:a5:32:13:29' ];
and here is the function that returns the match if found
$scope.getList = function(){
// $scope.wifiList = WifiService.list();
var c = $scope.MacA;
var m = WifiService.list();
for(var i = 0;i < c.length;i++) {
for(var j = i;j < m.length;j++) { // Notice the j = i;
if (c[i].name === m[j]) {
$scope.result = c[i].sector;
// $scope.result = 'Its working';
break;
} else {
$scope.result = "Sorry!";
}
};
};
return $scope.result;
}
You didn't specify what exactly you want as the result, but here is a possible version that looks for matches.
var result = [];
match.forEach(m => result.push(MacA.find(macA => macA.name === m)));
MacA = [
{
name: '24:fd:52:c3:d8:35',
sector: 'A23'
},
{
name: '56:db:30:4b:57:45',
sector: 'It support'
},
{
name: 'b6:b6:76:6b:e9:00',
sector: 'A24'
},
{
name: 'e8:74:e6:a1:14:16',
sector: 'Vodafone Guest'
},
{
name: 'dc:4a:3e:b7:32:0e',
sector: 'Direct HP officejet'
},
{
name: '7c:4c:a5:32:13:29',
sector: 'skyb7'
}
]
Match = ['dc:4a:3e:b7:32:0e','7c:4c:a5:32:13:29' ];
MacA.filter(({name}) => Match.includes(name)).map(({sector}) => sector)
// RETURNS // ["Direct HP officejet", "skyb7"]
SO, given your code above, something like this:
$scope.getList = function(){
return $scope.result = $scope.MacA.filter(({name}) => $scope.match.includes(name)).map(({sector}) => sector)
}
I've refactored some of your code.
$scope.getList = function(){
var devices = $scope.MacA;
var macList = WifiService.list();
var results = devices.reduce((acc, device) => acc.concat(macList.find(current.name)? [current.sector]:[]), []);
return results.length? $scope.results = results : $scope.results = 'Sorry!';
}
I inherited on the point_of_sale models.js file in order to add a model. This by following code:
openerp.dewieuw = function(instance, local) { //module is instance.point_of_sale
var module = instance.point_of_sale;
var QWeb = instance.web.qweb;
var _t = instance.web._t;
var round_di = instance.web.round_decimals;
var round_pr = instance.web.round_precision
alert(instance.point_of_sale)
alert(module)
module.PosModel = module.PosModel.extend({
models: [
{
model: 'res.users',
fields: ['name','company_id'],
ids: function(self){ return [self.session.uid]; },
loaded: function(self,users){ self.user = users[0]; },
},{
model: 'res.company',
fields: [ 'currency_id', 'email', 'website', 'company_registry', 'vat', 'name', 'phone', 'partner_id' , 'country_id', 'tax_calculation_rounding_method'],
ids: function(self){ return [self.user.company_id[0]] },
loaded: function(self,companies){ self.company = companies[0]; },
},{
model: 'decimal.precision',
fields: ['name','digits'],
loaded: function(self,dps){
self.dp = {};
for (var i = 0; i < dps.length; i++) {
self.dp[dps[i].name] = dps[i].digits;
}
},
},{
model: 'product.uom',
fields: [],
domain: null,
loaded: function(self,units){
self.units = units;
var units_by_id = {};
for(var i = 0, len = units.length; i < len; i++){
units_by_id[units[i].id] = units[i];
units[i].groupable = ( units[i].category_id[0] === 1 );
units[i].is_unit = ( units[i].id === 1 );
}
self.units_by_id = units_by_id;
}
},{
model: 'res.users',
fields: ['name','ean13'],
domain: null,
loaded: function(self,users){ self.users = users; },
},{
model: 'res.partner',
fields: ['name','street','city','state_id','country_id','vat','phone','zip','mobile','email','ean13','write_date','nieuwsbrief','klantgroep','lang'],
domain: [['customer','=',true]],
loaded: function(self,partners){
self.partners = partners;
self.db.add_partners(partners);
},
},{
model: 'res.lang',
fields: ['name', 'code'],
loaded: function(self,langs){
self.langs = langs;
},
},{
model: 'klantgroep',
fields: ['name'],
loaded: function(self,klantgroepen){
self.klantgroepen = klantgroepen;
},
},{
model: 'res.country',
fields: ['name'],
loaded: function(self,countries){
self.countries = countries;
self.company.country = null;
for (var i = 0; i < countries.length; i++) {
if (countries[i].id === self.company.country_id[0]){
self.company.country = countries[i];
}
}
},
},{
model: 'account.tax',
fields: ['name','amount', 'price_include', 'include_base_amount', 'type', 'child_ids', 'child_depend', 'include_base_amount'],
domain: null,
loaded: function(self, taxes){
self.taxes = taxes;
self.taxes_by_id = {};
_.each(taxes, function(tax){
self.taxes_by_id[tax.id] = tax;
});
_.each(self.taxes_by_id, function(tax) {
tax.child_taxes = {};
_.each(tax.child_ids, function(child_tax_id) {
tax.child_taxes[child_tax_id] = self.taxes_by_id[child_tax_id];
});
});
},
},{
model: 'pos.session',
fields: ['id', 'journal_ids','name','user_id','config_id','start_at','stop_at','sequence_number','login_number'],
domain: function(self){ return [['state','=','opened'],['user_id','=',self.session.uid]]; },
loaded: function(self,pos_sessions){
self.pos_session = pos_sessions[0];
var orders = self.db.get_orders();
for (var i = 0; i < orders.length; i++) {
self.pos_session.sequence_number = Math.max(self.pos_session.sequence_number, orders[i].data.sequence_number+1);
}
},
},{
model: 'pos.config',
fields: [],
domain: function(self){ return [['id','=', self.pos_session.config_id[0]]]; },
loaded: function(self,configs){
self.config = configs[0];
self.config.use_proxy = self.config.iface_payment_terminal ||
self.config.iface_electronic_scale ||
self.config.iface_print_via_proxy ||
self.config.iface_scan_via_proxy ||
self.config.iface_cashdrawer;
self.barcode_reader.add_barcode_patterns({
'product': self.config.barcode_product,
'cashier': self.config.barcode_cashier,
'client': self.config.barcode_customer,
'weight': self.config.barcode_weight,
'discount': self.config.barcode_discount,
'price': self.config.barcode_price,
});
if (self.config.company_id[0] !== self.user.company_id[0]) {
throw new Error(_t("Error: The Point of Sale User must belong to the same company as the Point of Sale. You are probably trying to load the point of sale as an administrator in a multi-company setup, with the administrator account set to the wrong company."));
}
},
},{
model: 'stock.location',
fields: [],
ids: function(self){ return [self.config.stock_location_id[0]]; },
loaded: function(self, locations){ self.shop = locations[0]; },
},{
model: 'product.pricelist',
fields: ['currency_id'],
ids: function(self){ return [self.config.pricelist_id[0]]; },
loaded: function(self, pricelists){ self.pricelist = pricelists[0]; },
},{
model: 'res.currency',
fields: ['symbol','position','rounding','accuracy'],
ids: function(self){ return [self.pricelist.currency_id[0]]; },
loaded: function(self, currencies){
self.currency = currencies[0];
if (self.currency.rounding > 0) {
self.currency.decimals = Math.ceil(Math.log(1.0 / self.currency.rounding) / Math.log(10));
} else {
self.currency.decimals = 0;
}
},
},{
model: 'product.packaging',
fields: ['ean','product_tmpl_id'],
domain: null,
loaded: function(self, packagings){
self.db.add_packagings(packagings);
},
},{
model: 'pos.category',
fields: ['id','name','parent_id','child_id','image'],
domain: null,
loaded: function(self, categories){
self.db.add_categories(categories);
},
},{
model: 'product.product',
fields: ['display_name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code',
'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description',
'product_tmpl_id'],
domain: [['sale_ok','=',true],['available_in_pos','=',true]],
context: function(self){ return { pricelist: self.pricelist.id, display_default_code: false }; },
loaded: function(self, products){
self.db.add_products(products);
},
},{
model: 'account.bank.statement',
fields: ['account_id','currency','journal_id','state','name','user_id','pos_session_id'],
domain: function(self){ return [['state', '=', 'open'],['pos_session_id', '=', self.pos_session.id]]; },
loaded: function(self, bankstatements, tmp){
self.bankstatements = bankstatements;
tmp.journals = [];
_.each(bankstatements,function(statement){
tmp.journals.push(statement.journal_id[0]);
});
},
},{
model: 'account.journal',
fields: [],
domain: function(self,tmp){ return [['id','in',tmp.journals]]; },
loaded: function(self, journals){
self.journals = journals;
// associate the bank statements with their journals.
var bankstatements = self.bankstatements;
for(var i = 0, ilen = bankstatements.length; i < ilen; i++){
for(var j = 0, jlen = journals.length; j < jlen; j++){
if(bankstatements[i].journal_id[0] === journals[j].id){
bankstatements[i].journal = journals[j];
}
}
}
self.cashregisters = bankstatements;
},
},{
label: 'fonts',
loaded: function(self){
var fonts_loaded = new $.Deferred();
// Waiting for fonts to be loaded to prevent receipt printing
// from printing empty receipt while loading Inconsolata
// ( The font used for the receipt )
waitForWebfonts(['Lato','Inconsolata'], function(){
fonts_loaded.resolve();
});
// The JS used to detect font loading is not 100% robust, so
// do not wait more than 5sec
setTimeout(function(){
fonts_loaded.resolve();
},5000);
return fonts_loaded;
},
},{
label: 'pictures',
loaded: function(self){
self.company_logo = new Image();
var logo_loaded = new $.Deferred();
self.company_logo.onload = function(){
var img = self.company_logo;
var ratio = 1;
var targetwidth = 300;
var maxheight = 150;
if( img.width !== targetwidth ){
ratio = targetwidth / img.width;
}
if( img.height * ratio > maxheight ){
ratio = maxheight / img.height;
}
var width = Math.floor(img.width * ratio);
var height = Math.floor(img.height * ratio);
var c = document.createElement('canvas');
c.width = width;
c.height = height
var ctx = c.getContext('2d');
ctx.drawImage(self.company_logo,0,0, width, height);
self.company_logo_base64 = c.toDataURL();
logo_loaded.resolve();
};
self.company_logo.onerror = function(){
logo_loaded.reject();
};
self.company_logo.crossOrigin = "anonymous";
self.company_logo.src = '/web/binary/company_logo' +'?_'+Math.random();
return logo_loaded;
},
},
],
});
module.ClientListScreenWidget = module.ClientListScreenWidget.extend({
// what happens when we save the changes on the client edit form -> we fetch the fields, sanitize them,
// send them to the backend for update, and call saved_client_details() when the server tells us the
// save was successfull.
save_client_details: function(partner) {
var self = this;
var fields = {}
this.$('.client-details-contents .detail').each(function(idx,el){
fields[el.name] = el.value;
if(el.name=='nieuwsbrief'){
fields[el.name] = el.checked;
}
});
if (!fields.name) {
this.pos_widget.screen_selector.show_popup('error',{
message: _t('A Customer Name Is Required'),
});
return;
}
if (this.uploaded_picture) {
fields.image = this.uploaded_picture;
}
fields.id = partner.id || false;
fields.country_id = fields.country_id || false;
fields.ean13 = fields.ean13 ? this.pos.barcode_reader.sanitize_ean(fields.ean13) : false;
new instance.web.Model('res.partner').call('create_from_ui',[fields]).then(function(partner_id){
self.saved_client_details(partner_id);
},function(err,event){
event.preventDefault();
self.pos_widget.screen_selector.show_popup('error',{
'message':_t('Error: Could not Save Changes'),
'comment':_t('Your Internet connection is probably down.'),
});
});
},
});
}
This worked like a charm. But now I wanted to inherit on the website_sale.js file so I added some test code to this file. And now I always get this error:
TypeError: module.PosModel is undefined
I deleted this test code, but still the error occurs. Any ideas? I also placed my whole module back to a backup were everything worked fine, but I'm still getting this error.
Have you added point_of_sale dependency in website_sale module openerp.py file ?
If not, please add it and try again.
I am having jqgrid this way,
<div id="dialogLoading" style="position:absolute;z-index:1005">
<img src="http://blog.teamtreehouse.com/wp-content/uploads/2015/05/InternetSlowdown_Day.gif" />
</div>
<table id="list"></table>
$(function () {
var blueArray = [];
for (var i=1;i<=4000;i++) {
blueArray.push(i);
}
var greenArray = [];
for (var i=4000;i<=6000;i++) {
greenArray.push(i);
}
var redArray = [];
for (var i=6000;i<=8000;i++) {
redArray.push(i);
}
var yellowArray = [];
for (var i=8000;i<=10000;i++) {
yellowArray.push(i);
}
"use strict";
var getGridData = function(n) {
var data = [], i;
for (i = 0; i < n; i++) {
data.push({
id: (i + 1)*10,
aa: "aa" + i, // colunn 1
bb: "bb" + (i%3), // colunn 2
cc: "cc" + (i%5), // colunn 3
dd: "dd" + (i%7), // colunn 4
ee: "ee" + (i%11), // colunn 5
ff: "ff" + (i%13), // colunn 6
gg: "gg" + (i%17), // colunn 7
hh: "hh" + (i%19), // colunn 8
ii: "ii" + (i%23), // colunn 9
jj: "jj" + (i%29), // colunn 10
kk: "kk" + (i%31), // colunn 11
ll: "ll" + (i%37), // colunn 12
mm: "mm" + (i%41) // colunn 13
});
}
return data;
},
$grid = $("#list"),
gridData,
startTime,
measureTime = false,
timeInterval;
gridData = getGridData(10000);
startTime = new Date();
$grid.jqGrid({
data: gridData,
colModel: [
{ name: "aa", label: "c01" },
{ name: "bb", label: "c02" },
{ name: "cc", label: "c03" },
{ name: "dd", label: "c04" },
{ name: "ee", label: "c05" },
{ name: "ff", label: "c06" },
{ name: "gg", label: "c07" },
{ name: "hh", label: "c08" },
{ name: "ii", label: "c09" },
{ name: "jj", label: "c10" },
{ name: "kk", label: "c11" },
{ name: "ll", label: "c12" },
{ name: "mm", label: "c13" }
],
cmTemplate: { width: 100, autoResizable: true },
iconSet: "fontAwesome",
rowNum: 10000,
rownumWidth: 40,
//rowList: [20, 100, 1000, 10000, "100000:All"],
viewrecords: true,
rownumbers: true,
//toppager: true,
//pager: true,
shrinkToFit: false,
rowattr: function (rd) {
var rowIds = $("#list").jqGrid('getDataIDs');
console.log(rowIds);
if(blueArray.indexOf(rowIds) > -1)
return {"class": "blue"}
else if(greenArray.indexOf(rowIds) > -1)
return {"class": "green"}
else if(redArray.indexOf(rowIds) > -1)
return {"class": "yellow"}
else
return {"class": "one"}
},
loadComplete: function () {
closeDialogLoading();
if (measureTime) {
setTimeout(function () {
alert("Total loading time: " + timeInterval + "ms");
}, 50);
measureTime = false;
}
},
autoencode: true,
caption: "Shows the performance of resizing. Make double-click on the column resizer"
}).jqGrid("gridResize");
timeInterval = new Date() - startTime;
setTimeout(function () {
alert("Total time: " + timeInterval + "ms");
}, 50);
function openDialogLoading(){
$("#dialogLoading").css("display", "");
}
function closeDialogLoading(){
$("#dialogLoading").hide();
}
});
css:
.one { background:red; }
.blue { background:blue; }
.green { background:green; }
.yellow { background:yellow; }
I am trying to chaNge the row color of the jqgrid comparing each rowid with an array of values.
Here is the logic for that,
rowattr: function (rd) {
var rowIds = $("#list").jqGrid('getDataIDs');
console.log(rowIds);
if(blueArray.indexOf(rowIds) > -1)
return {"class": "blue"}
else if(greenArray.indexOf(rowIds) > -1)
return {"class": "green"}
else if(redArray.indexOf(rowIds) > -1)
return {"class": "yellow"}
else
return {"class": "one"}
the problem here is, rowIds are getting as empty []. so always my condition i going to else and red color is shown on each row's.
I need to check if rowid is exists in blueArray,greenArray e.t.c if its is true paint that row with the corresponding color.
In my example my bluearray has values from 1 to 4000. So all these records from 1 to 4000 have to be painted in blue.
My logic inside rowattr: block is not working as i am getting rowid as empty[].
How to get rowid inside rowattr: function (rd) {} block of jqrid?
The above logic working is fine in loadcomplete and gridcomplete events but it is blocking entire ui and taking hell lot of time to load grid.
Can anyone help me in this issue?
Thanks
You need just use rd.id inside of rowattr:
rowattr: function (rd) {
if (blueArray.indexOf(rd.id) > -1) {
return {"class": "blue"};
} else if (greenArray.indexOf(rd.id) > -1) {
return {"class": "green"};
} else if (redArray.indexOf(rd.id) > -1) {
return {"class": "red"};
} else {
return {"class": "one"};
}
}
the demo uses the code, but it's really slowly because you create 13x10000 cells in the grid. I recommend to open the demo only in Chrome where it takes still about 15 sec.
I strictly recommend to use local paging. Look at almost the same demo where the page size is 25 instead of absolute unneeded 10000. It works really quickly. One can jump on the page 200 or 300 to see another colors.