handlebars returning index along with data - indexing

I have a helper that loops through jason data till a given value and sends the data back to the template.I also want to show at what location the data is present (the index), is there any way where in i can return the Index value along with the data?
Handlebars.registerHelper('print_range', function(items,count,options)
{
var out = "";
for(var i=0, l=items.length; i<count; i++)
{
out = out + options.fn(items[i]);
}
return out;
});
<script id="template" type="text/x-handlebars-template">
{{#print_range options "2"}}
<h1>index</h1> // this index should correspond to i in the helper function
<h2>{{optionID}}{{nextID}}</h2>
{{/print_range}}
</script>
Thanks in advance.

Handlebars.registerHelper('print_range', function(items,count,options)
{{#print_range options "2"}}
Not sure 100% what you're asking, but i do see a problem in your code. You specify 3 parameters in the function, but only give it 2 in your statement call to the helper.
{{#print_range options "2"}}
^ fn name ^items ^ count
Where's the value for your options variable? In handlebars, the parameters for the function go in order after the helper name you are calling

Related

How can I save part of a string in an alias using Cypress?

I'm trying to save just a number from a string I get from a paragraph but when I try to asign an alias to it and then check the value it returns undefined. I've tried a few solutions I found but none of those seem to work for me. These are two ways I tried (I tried another one similar to the second one but using split, had same result). The console.log inside of the 'then' doesn't show in the console, and when I try the alias after the code is when I get undefined.
cy.get('p')
.eq(1)
.should('have.text', '/[0-9]+/g')
.as('solNumber')
cy.get('p')
.eq(1)
.invoke('text')
.then((text)=>{
var fullText = text;
var pattern = /[0-9]+/g;
var number = fullText.match(pattern);
console.log(number);
})
.as('solNumber')
Please convert with + operator and return the numeric value if you want numeric type to be stored.
cy.get('p').eq(1)
.invoke('text')
.then(fullText => {
const number = fullText.match(/[0-9]+/);
return +number // text to numeric
})
.as('solNumber')
cy.get('#solNumber')
.should('eq', 42) // numeric type
});
Running your 2nd code on this,
<p>21</p>
<p>42</p>
gives the correct outcome
cy.get('p')
.eq(1)
.invoke('text')
.then((text)=>{
var fullText = text;
var pattern = /[0-9]+/g;
var number = fullText.match(pattern);
console.log(number); // logs 42
})
.as('solNumber')
cy.get('#solNumber')
.should('eq', '42') // passes
So, you need to inspect the DOM, it looks like it's not what you expect.
The first attempt you were passing a jquery element to the .should() and although some chainers change the subject yours did not so it saved the jquery element as solNumber.
The second attempt invokes the .text() which was passed to the .then() it logs the number correctly. However, you did not return anything at the end of the .then() block, therefore, solNumber should hold the entire paragraph.
This should help you out to extract the specific number and save it as an alias.
cy.get('p')
.invoke('text')
.invoke('trim')
.then(paragraph => {
const matcher = /some/
expect(paragraph).to.match(matcher) // check number is there
const indexOfText = paragraph.match(matcher) // get index of match text
return paragraph.substring(indexOfText.index, indexOfText.index + indexOfText[0].length) // return substring
})
.as('savedText')
cy.get('#savedText')
.then(cy.log) // will print out the number you seek

columnSummary is not added

I am trying to add columnSummary to my table using Handsontable. But it seems that the function does not fire. The stretchH value gets set and is set properly. But it does not react to the columnSummary option:
this.$refs.hot.hotInstance.updateSettings({stretchH: 'all',columnSummary: [
{
destinationRow: 0,
destinationColumn: 2,
reversedRowCoords: true,
type: 'custom',
customFunction: function(endpoint) {
console.log("TEST");
}
}]
}, false);
I have also tried with type:'sum' without any luck.
Thanks for all help and guidance!
columnSummary cannot be changed with updateSettings: GH #3597
You can set columnSummary settings at the initialization of Handsontable.
One workaround would be to somehow manage your own column summary, since Handsontable one could give you some headeache. So you may try to add one additional row to put your arithmetic in, but it is messy (it needs fixed rows number and does not work with filtering and sorting operations. Still, it could work well under some circumstances.
In my humble opinion though, a summary column has to be fully functionnal. We then need to set our summary row out of the table data. What comes to mind is to take the above mentioned additional row and take it away from the table data "area" but it would force us to make that out of the table row always looks like it still was in the table.
So I thought that instead of having a new line we could just have to add our column summary within column header:
Here is a working JSFiddle example.
Once the Handsontable table is rendered, we need to iterate through the columns and set our column summary right in the table cell HTML content:
for(var i=0;i<tableConfig.columns.length;i++) {
var columnHeader = document.querySelectorAll('.ht_clone_top th')[i];
if(columnHeader) { // Just to be sure column header exists
var summaryColumnHeader = document.createElement('div');
summaryColumnHeader.className = 'custom-column-summary';
columnHeader.appendChild( summaryColumnHeader );
}
}
Now that our placeholders are set, we have to update them with some arithmetic results:
var printedData = hotInstance.getData();
for(var i=0;i<tableConfig.columns.length;i++) {
var summaryColumnHeader = document.querySelectorAll('.ht_clone_top th')[i].querySelector('.custom-column-summary'); // Get back our column summary for each column
if(summaryColumnHeader) {
var res = 0;
printedData.forEach(function(row) { res += row[i] }); // Count all data that are stored under that column
summaryColumnHeader.innerText = '= '+ res;
}
}
This piece of code function may be called anytime it should be:
var hotInstance = new Handsontable(/* ... */);
setMySummaryHeaderCalc(); // When Handsontable table is printed
Handsontable.hooks.add('afterFilter', function(conditionsStack) { // When Handsontable table is filtered
setMySummaryHeaderCalc();
}, hotInstance);
Feel free to comment, I could improve my answer.

Javascript with a for in loop

working on the follow code. Having some issues with taking the user input from the day and the temp. I have a start but again running into an issue with Step 2 & 3 unable to pass the information to the array and figure out how to display it. Any insight and direction would be greatly appreciated. Thanks
var temperatures = [];
var days = ["Monday", "Tuesday","Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
var $ = function (id) {
return document.getElementById(id);
}
var takeTemps = function () {
//###STEP 2
//Get the user inputted temp, validate it making sure it's a number
//if it's valid add it to the temperatures array at the index that
// corresponds with the day of week, e.g. 0 for Monday, 2 for Wednesday
var userTemp=(parseFloat($("tempIn").value));
while (!isNaN(tempIn)==true)
{
alert("Please enter a numeric value");
$("tempIn").focus();
}
//This gets the value from the selected menu option
var index = $("daySelect").value;
for(var dayTemp in temperatures)
{
var daily=temperatures[index]
}
//remove this when done, this just tests your menu you wrote for step 1
alert( index + " indexes day " + days[index]+ userTemp);
//Call displayTemps ONLY if the temp input was valid.
displayTemps();
//EXTRA work / not credit
// have it auto advance the selected day in the menu
// by assigning into $("daySelect").value
// If it was on Sunday change it to Monday and only on valid input
}
var displayTemps = function () {
//###STEP 3
//loop through non-undefined indexes in the temperatures array
//appended them to tempString adding the day .e.x
//Tuesday: 89
//Friday: 98
//display the string to the page by setting the value of the textarea
//
//In the same loop sum the temperatures and count
// how many there are so you can calculate the average
// and output the average temp on the page.
tempString = "";
tempTemp = 0;
for(var i in temperatures) {
tempString += index + ": " + temperatures[i];
}
document.write(tempString + "<br>");
var average =tempTemp+10;
$("tempList").value=tempString;
$("avgOut").value=average;
}
window.onload = function () {
$("addTemp").onclick = takeTemps;
//###STEP 1
//Use a for loop here to write options to the select for each day of the week
// <option value="0">Monday</option>
// using += here with innerHTML property takes the existing values and concats this on the end
for (var i =0; i<7; i++)
{
$("daySelect").innerHTML += "<option value=\""+ i + "\">" + days[i] + "</option>\n";
$("daySelect").value = "";
//var day=i-1;
//var day = days[i];
}
$("tempIn").focus();
}
Struggles with Step 2 and 3 Beleive i have #1 good to go I have enclosed the HTML for reference
<html>
<head>
<script src=script.js></script>
<head>
<body>
<section>
<select id="daySelect">
<option value="">Select a day</option>
</select>
<input type="text" id="tempIn">
<input type="button" id="addTemp" value="add temperature">
<br>
<br>
<label for="tempList">Temperature List</label>
<br>
<textarea id="tempList" rows="7" cols="50"></textarea>
<br>
<label>Average Temperature</label>
<input type="text" id="avgOut" disabled>
</section>
</body></html>
I would suggest to provide more specific information about which part of the code you are concerned with, and especially, provide the HTML code as well since that would enable us to see more clearly what you are trying to do.
When you are done, I will edit this answer and you will get appropriate guidance.
Keep coding!
EDIT
Take a look:
var userTemp=(parseFloat($("tempIn").value));
while (!isNaN(tempIn)==true)
{
alert("Please enter a numeric value");
$("tempIn").focus();
}
Looking at this little piece of code from "Step 2", I can think of a number of bugs already. Of course I'm not sure since I haven't seen your HTML yet, but it seems like:
You have put the value of the input into a variable named userTemp, yet you are checking for a variable named "tempIn" for validation. The second one probably doesn't exist at that point in time. "tempIn" was the name of your DOM element, not the JS variable you've assigned its value. You have to check for the userTemp variable.
In your validation, you are checking for the opposite of isNaN. NaN means "Not a Number", so the opposite of that would be actually number, so the statement is wrong. Not to mention that in this, you would not need to explicitly express "==true", you can check like this: while(isNaN(userTemp))
If you want to iterate a while statement for validation until you get a valid number, you need to put the variable assignment inside the while statement, since you'll need to try to assign the new number each time the validation loop iterates.
EDIT 2 - finished
Your code is live here:
https://codepen.io/bradib0y/pen/OBEdvp?editors=1010
Please note that if you are working your way through a course and this was your assessment, you've gained exactly nothing with me making these tasks for you. You will only gain from getting throught these challenges yourself.
I suggest to spend at least 1 hour with analyzing this code step by step and try to replicate it in a similar project. If you still have struggle with understanding, do yourself a favor and start over with basic javascript once again. You will be an expert on this within a week, if you put the basics down right. But if you still can't grasp the basics and keep pushing forward with more complex issues, you will have a hard time.

"update" query - error invalid input synatx for integer: "{39}" - postgresql

I'm using node js 0.10.12 to perform querys to postgreSQL 9.1.
I get the error error invalid input synatx for integer: "{39}" (39 is an example number) when I try to perform an update query
I cannot see what is going wrong. Any advise?
Here is my code (snippets) in the front-end
//this is global
var gid=0;
//set websockets to search - works fine
var sd = new WebSocket("ws://localhost:0000");
sd.onmessage = function (evt)
{
//get data, parse it, because there is more than one vars, pass id to gid
var received_msg = evt.data;
var packet = JSON.parse(received_msg);
var tid = packet['tid'];
gid=tid;
}
//when user clicks button, set websockets to send id and other data, to perform update query
var sa = new WebSocket("ws://localhost:0000");
sa.onopen = function(){
sa.send(JSON.stringify({
command:'typesave',
indi:gid,
name:document.getElementById("typename").value,
}));
sa.onmessage = function (evt) {
alert("Saved");
sa.close;
gid=0;//make gid 0 again, for re-use
}
And the back -end (query)
var query=client.query("UPDATE type SET t_name=$1,t_color=$2 WHERE t_id = $3 ",[name, color, indi])
query.on("row", function (row, result) {
result.addRow(row);
});
query.on("end", function (result) {
connection.send("o");
client.end();
});
Why this not work and the number does not get recognized?
Thanks in advance
As one would expect from the initial problem, your database driver is sending in an integer array of one member into a field for an integer. PostgreSQL rightly rejects the data and return an error. '{39}' in PostgreSQL terms is exactly equivalent to ARRAY[39] using an array constructor and [39] in JSON.
Now, obviously you can just change your query call to pull the first item out of the JSON array. and send that instead of the whole array, but I would be worried about what happens if things change and you get multiple values. You may want to look at separating that logic out for this data structure.

Conditionally adjust visible columns in Rally Cardboard UI

So I want to allow the user to conditionally turn columns on/off in a Cardboard app I built. I have two problems.
I tried using the 'columns' attribute in the config but I can't seem to find a default value for it that would allow ALL columns to display(All check boxes checked) based on the attribute, ie. the default behavior if I don't include 'columns' in the config object at all (tried null, [] but that displays NO columns).
So that gets to my second problem, if there is no default value is there a simple way to only change that value in the config object or do I have to encapsulate the entire variable in 'if-else' statements?
Finally if I have to manually build the string I need to parse the values of an existing custom attribute (a drop list) we have on the portfolio object. I can't seem to get the rally.forEach loop syntax right. Does someone have a simple example?
Thanks
Dax - Autodesk
I found a example in the online SDK from Rally that I could modify to answer the second part (This assumes a custom attribute on Portfolio item called "ADSK Kanban State" and will output values to console) :
var showAttributeValues = function(results) {
for (var property in results) {
for (var i=0 ; i < results[property].length ; i++) {
console.log("Attribute Value : " + results[property][i]);
}
}
};
var queryConfig = [];
queryConfig[0] = {
type: 'Portfolio Item',
key : 'eKanbanState',
attribute: 'ADSK Kanban State'
};
rallyDataSource.findAll(queryConfig, showAttributeValues);
rally.forEach loops over each key in the first argument and will execute the function passed as the second argument each time.
It will work with either objects or arrays.
For an array:
var array = [1];
rally.forEach(array, function(value, i) {
//value = 1
//i = 0
});
For an object:
var obj = {
foo: 'bar'
};
rally.forEach(obj, function(value, key) {
//value = 'bar'
//key = 'foo'
});
I think that the code to dynamically build a config using the "results" collection created by your query above and passed to your sample showAttributeValues callback, is going to look a lot like the example of dynamically building a set of Table columns as shown in:
Rally App SDK: Is there a way to have variable columns for table?
I'm envisioning something like the following:
// Dynamically build column config array for cardboard config
var columnsArray = new Array();
for (var property in results) {
for (var i=0 ; i < results[property].length ; i++) {
columnsArray.push("'" + results[property][i] + "'");
}
}
var cardboardConfig = {
{
attribute: 'eKanbanState',
columns: columnsArray,
// .. rest of config here
}
// .. (re)-construct cardboard...
Sounds like you're building a neat board. You'll have to provide the board with the list of columns to show each time (destroying the old board and creating a new one).
Example config:
{
attribute: 'ScheduleState'
columns: [
'In-Progress',
'Completed'
]
}