Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
liam_hanninen
Creator
Creator

Reference hypercube or chart values in JavaScript

Hi all,

We hope to do something very cool with Qlik Sense Mash-ups. We want to allow users to enter text into an empty text field that's within a table. And then hope to  reference some of that other data on that same row in the table where they entered that text in the JavaScript/html input/form to be sent as a POST request to an API.

This would allow them to post to our API via Qlik! So I think I have two questions:

1) How to make a text input box within a qlik sense table OR if this is not possible I think I'll just have to use hypercube to build an html table that would have an input box.

2) How to use the Qlik API to pull contents from that specific row in the Qlik table into a POST json. Again if this is not possible I'll have to go from the ground-up to build a html table.

1 Solution

Accepted Solutions
m_s
Partner - Creator II
Partner - Creator II

Hello Liam,

I thought this was an interesting use case so I built a little POC for you:

var app = qlik.openApp('456942a2-d3e2-40a5-bad6-985e80294f05', config);

app.getObject('QV01', 'BSNjEu').then(model => {

console.log('loaded:', model);

var table = qlik.table(model);

// set timeout for now, some invalidated event would probably be a better fit

setTimeout(() => {

console.log('table:', table);

$('#QV01 [tid] .qv-st-data table tbody tr').each((i, tr) => {

var input = $('<input type="text" class="lui-input"/>');

var data = {};

$(tr).find('td').each((i, td) => {

td = $(td);

// get cell object from angular scope

var cell = angular.element(td).scope().cell;

if(cell.type == undefined || cell.dataColIx < 0)

return;

var header = table.headers[cell.dataColIx];

var column = header.field ? header.field.fldname : header.qFallbackTitle;

// create property for this cell

// using either field name or table header

// and append value to row data object

data[column] = cell.text;

// append input field after

var isLast = table.colCount == td.index() + 1;

if(isLast) {

td.after(input);

input.wrap($('<td class="qv-st-data-cell"><div class="qv-st-value"></div></td>'));

}

});

// save data for later use

input.data(data);

// and assign change event handler

input.change(function(){

var value = $(this).val();

var data = $(this).data();

data.inputValue = value;

console.log('sending data: ', data);

});

});

}, 1000);

This should work for straight tables but the're probably some issues as this is just a small example. I also don't know how this will perform on very big tables.

example.jpg

Hope this helps you,

Mathias

View solution in original post

10 Replies
m_s
Partner - Creator II
Partner - Creator II

Hello Liam,

I thought this was an interesting use case so I built a little POC for you:

var app = qlik.openApp('456942a2-d3e2-40a5-bad6-985e80294f05', config);

app.getObject('QV01', 'BSNjEu').then(model => {

console.log('loaded:', model);

var table = qlik.table(model);

// set timeout for now, some invalidated event would probably be a better fit

setTimeout(() => {

console.log('table:', table);

$('#QV01 [tid] .qv-st-data table tbody tr').each((i, tr) => {

var input = $('<input type="text" class="lui-input"/>');

var data = {};

$(tr).find('td').each((i, td) => {

td = $(td);

// get cell object from angular scope

var cell = angular.element(td).scope().cell;

if(cell.type == undefined || cell.dataColIx < 0)

return;

var header = table.headers[cell.dataColIx];

var column = header.field ? header.field.fldname : header.qFallbackTitle;

// create property for this cell

// using either field name or table header

// and append value to row data object

data[column] = cell.text;

// append input field after

var isLast = table.colCount == td.index() + 1;

if(isLast) {

td.after(input);

input.wrap($('<td class="qv-st-data-cell"><div class="qv-st-value"></div></td>'));

}

});

// save data for later use

input.data(data);

// and assign change event handler

input.change(function(){

var value = $(this).val();

var data = $(this).data();

data.inputValue = value;

console.log('sending data: ', data);

});

});

}, 1000);

This should work for straight tables but the're probably some issues as this is just a small example. I also don't know how this will perform on very big tables.

example.jpg

Hope this helps you,

Mathias

liam_hanninen
Creator
Creator
Author

Mathias,

Very cool! Thanks for taking a stab at it. I will try this later today. Two quick questions that are probably obvious to you but:

1) When I try to replicate this can I just switch out the app id and object id for the table? Or do I need to change anything else?

2) It looks like var data is what would be the content from the text box. Is that correct?

m_s
Partner - Creator II
Partner - Creator II

Hello Liam,

Yes you can just switch the app and object id.

No, the data variable contains the row-data for the current input field (should've probably named the variable on line 14 rowData in the first place ).

You can see the content of the data variable in the screenshot just below the code snippet. Thats the output of the "console.log" statement on line 53.

Line 12 to 31 are responsible for looping over the table rows and their columns creating a javascript object for every row in the following form:

{

"FIELD NAME1 OR COLUMN HEADER1": "VALUE OF COLUMN1",

"FIELD NAME2 OR COLUMN HEADER2": "VALUE OF COLUMN2",

}

Line 34 to 41 are appending a <td> element containing the input field after the last data column and line 44 uses the jQuery .data method to append custom data to an html element (think of data-blabla attributes).

Line 47-54 assigns an event handler for the changed event (will be triggered after you tab out of the textbox), extracts the object that was set in line 44 and creates a property "inputValue" with the <input>-elements current value.

So the data variable contains probably everything you want to send to your REST API.

Mathias

liam_hanninen
Creator
Creator
Author

Mathias,

Thanks so much! I was able to replicate it on a mash-up. I see the text box and I can type in it. I'm noticing some strange behavior that maybe was expected but it's saying: 'Uncaught TypeError: Cannot read property 'dataColIx' of undefined' whenever I highlight the text within the text box - for each character of the text box.

2017_09_11_12_46_17_Qlik_Sense_Mashup.png

m_s
Partner - Creator II
Partner - Creator II

Liam,

Which version of Qlik Sense are you using? The server I built this on is running on June 2017 Patch 2, maybe the property does not exist in older versions?

The dataColIx-property is only used for extracting the header information from the table api (either fieldName or fallbackTitle). Maybe you can use the td.index() method instead.

Mathias

liam_hanninen
Creator
Creator
Author

Thanks! That helps. One last thing I think this is something you'll be able to answer really quickly; I just want to know how to add a title to that new column with the text fields.

m_s
Partner - Creator II
Partner - Creator II

You're welcome.

Try the following (just add it before line 12):

var customHeader = $('<th class="qv-st-header-cell"></th>');

customHeader.html('<div class="qv-st-value">EXTRACOLUMN</div>')

$('#QV01 [tid] .qv-st-header table tbody tr:first th').eq(-2).after(customHeader);

Mathias

liam_hanninen
Creator
Creator
Author

Thanks again for building this out m.schindler‌ I have  one more issue that you may be able to resolve pretty quickly. The hards part may be just demonstrating what the problem is haha. When I type in text and then scroll the text in each box stays in there as I scroll. Does that make sense? Please see screen shots.textBox1.png

textbox2.png

m_s
Partner - Creator II
Partner - Creator II

Hello Liam,

that happens because Qlik Sense creates a fixed amount of rows whose cell values are just switched out while scrolling. I played around a little bit but could not find an easy solution / workaround for this.

I think you're better off creating your own table extension. Maybe check out this link:

Simple table (extension example) ‒ Qlik Sense Developers

Mathias