Hello I am trying to append a custom type of cell I created to my backgrid instance but I keep getting the following error:
Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
I Console.logged the collection and the columns it turns out the above exception occurs on my custom cell. I think it is because it does not have a column attribute:
This is what my custom cell looks like:
return QuestionCell.extend({
distractors: ['-', 't', 'f'],
template: 'gradescreen/table/mc',
render: function () {
var $val_td, view = this, correct_td = '',
current_state = view.model.get('responses').stateModel.get('state'),
correct_answer = '', selected = '-', select = '', pos, key_length;
view.current_response = view.getCurrentResponse(view.model);
if (view.current_response.get('response').prefix) {
selected = view.current_response.get(
'response'
).prefix === 'a' ? 't':'f';
}
if (view.question_meta.get('correct_prefix') ===
view.current_response.get(
'response').prefix) {
correct_td = ' correct_td';
}
$val_td = $('<td class="response_td' + correct_td + '" />');
app.fetchTemplate(view.template, function (tmpl) {
$val_td.html(tmpl({cid: view.cid, q_number: view.question_number}));
key_length = _.keys(view.question_meta.get('answers')).length;
for (pos = 0; pos <= key_length; pos++) {
var prefix = view.distractors[pos];
correct_answer =
prefix === view.question_meta.get('correct_prefix') ?
'correct_response':'';
select = selected === prefix ? 'selected="true"':'';
$('#answer_options_' + view.cid, $val_td).append(
'<option class="' + correct_answer + '" ' + select + ' >' +
prefix + '</option>');
}
if (current_state > 2) {
$('#answer_options_' + view.cid, $val_td).prop('disabled', true);
}
//view.bindEvents($val_td);
});
this.el = $val_td;
return this;
}
});
});
It is extended from a cell I call as a QuestionCell which is extended from Backgrid.Cell and only contains from default attributes and methods.
This is how I am passing the cell to backgrid.
var grid, columns = [];
_.each(questions, function (question, position) {
if (question.get('type') === 'tf')
{
columns.push({
name: 'responses[0]',
label: 'Q-' + (position + 1),
cell: TFCell.extend({
question_meta : question,
question_number: position + 1,
group_id: view.group_id
})
});
}
else
{
//this last one isn't getting rendered for some reason.
columns.push({
label: 'Q-' + (position + 1),
cell: Backgrid.SelectCell.extend({
optionValues: [
['-', '-'], ['a', 'a'], ['b', 'b'],
['c', 'c'], ['d', 'd']
]
})
});
}
});
grid = new Backgrid.Grid({
columns: columns,
collection: view.model.get('student_responses')
});
$('#Student_Grid').append(grid.render().$el);
Please help. How can I get this to get rendered. Many Thanks
Reading through the documentation it looks like it's supposed to be
$('#Student_Grid').append(grid.render().el);
instead of
$('#Student_Grid').append(grid.render().$el);
$el looks like a function where as el is the node object that you'd want to append.
Related
I m using DataTable (Jquery) to export excel file. But I facing on how do put extra information to export excel file. I have tried some code but it didn't meet my expectation.
My expected exported excel file is as below picture:
However my output is as below picture, my title report and address is located at middle isn't on top of report:
with using code below:
{
extend: 'excelHtml5',
title: 'Trace Report',
messageTop: 'ABC company' + 'address',
//message: "Any message for header inside the file. I am not able to put message in next row in excel file but you can use \n"+'modelID'+modelId,
render: function (data, type, full, meta) {
return 'Download'; //change the button text here
},
customize: function (xlsx) {
var sheet = xlsx.xl.worksheets['sheet1.xml'];
var numrows = 10;
// add styles for the column header, these row will be moved down
var clRow = $('row', sheet);
//$(clRow[0]).find('c').attr('s', 32);
//update Row
clRow.each(function () {
var attr = $(this).attr('r');
var ind = parseInt(attr);
ind = ind + numrows;
//ind is num of row +1
$(this).attr("r", ind);
});
// Create row before data
$('row c ', sheet).each(function (index) {
var attr = $(this).attr('r');
var pre = attr.substring(0, 1);
//pre=A,B,C..-F repeat 5 time
var ind = parseInt(attr.substring(1, attr.length));
ind = ind + numrows;
$(this).attr("r", pre + ind);
});
function addRow(index, data) {
var row = sheet.createElement('row');
row.setAttribute("r", index);
for (i = 0; i < data.length; i++) {
var key = data[i].k;
var value = data[i].v;
var c = sheet.createElement('c');
c.setAttribute("t", "inlineStr");
c.setAttribute("s", "2"); /*set specific cell style here*/
c.setAttribute("r", key + index);
var is = sheet.createElement('is');
var t = sheet.createElement('t');
var text = sheet.createTextNode(value)
t.appendChild(text);
is.appendChild(t);
c.appendChild(is);
row.appendChild(c);
debugger;
}
return row;
}
//add data to extra rows
var countryStateList = 'asd';
var agencyValue = 'asd';
var reportGroupList = 'asd';
var certNo = '3e'
var r1 = addRow(1, [{
k: 'A',
v: 'Certificate Number'
}, {
k: 'B',
v: 'Model ID:'
}, {
k: 'C',
v: 'Serial Number'
}, {
k: 'D',
v: 'Calibration Date'
}]);
var r2 = addRow(2, [{
k: 'A',
v: countryStateList
}, {
k: 'B',
v: agencyValue
}, {
k: 'C',
v: reportGroupList
}, {
k: 'D',
v: certNo
}]); //add one cell for row 1
//$('row c[r^="A"]', sheet).attr( 's', '25' );
var sheetData = sheet.getElementsByTagName('sheetData')[0];
// sheetData.insertBefore(r4,sheetData.childNodes[0]);
// sheetData.insertBefore(r3,sheetData.childNodes[0]);
sheetData.insertBefore(r2, sheetData.childNodes[0]);
sheetData.insertBefore(r1, sheetData.childNodes[0]);
}
}
I am trying to export DataTable into excel file (.xlsx).
In jQuery, I am removing the unwanted rows.
When I try to open the excel file, it is showing:
"Excel found unreadable content in '[filename].xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes."
The error is showing as:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog
xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<logFileName>error128600_02.xml</logFileName><summary>Errors were detected
in file '[filename].xlsx'</summary><removedRecords summary="Following is a
list of removed records:"><removedRecord>Removed Records: Cell information
from /xl/worksheets/sheet1.xml part</removedRecord></removedRecords>
</recoveryLog>
The exported file is opening fine in OpenOffice with removed rows.
Here is the code to remove unwanted rows:
I have 5 Columns in my DataTable and removing the unwanted rows based on columns 3,4,5
customize: function (xlsx) {
var exportData=[];
var sheet =xlsx.xl.worksheets['sheet1.xml'];
var clR = $('row', sheet);
var clR = $('row', sheet);
$('row', sheet).filter(function () {
var attr = $(this).attr('r');
if(attr>3)
{
if($(this).context.children.length===5){
var Item1= parseInt($(this).context.children[2].children[0].textContent);
var Item2= parseInt($(this).context.children[3].children[0].textContent);
var Item3= parseInt($(this).context.children[4].children[0].textContent);
if(Item1===0 && Item2 ===0 && Item3===0 ){
return true;
}
else{
exportData.push([{ key: 'A', value: $(this).context.children[0].children[0].textContent },
{ key: 'B', value: $(this).context.children[1].children[0].textContent },
{ key: 'C', value: $(this).context.children[2].children[0].textContent },
{ key: 'D', value: $(this).context.children[3].children[0].textContent },
{ key: 'E', value: $(this).context.children[4].children[0].textContent }]);
}
return false;
}
}
}).remove();
//update Row
clR.each(function () {`enter code here`
var attr = $(this).attr('r');
var ind = parseInt(attr);
if(ind>3){
$(this).remove();
}
});
// Create row before data
$('row c ', sheet).each(function () {
var attr = $(this).attr('r');
var pre = attr.substring(0, 1);
if(pre>3){
$(this).remove();
}
});
function Addrow(index,data) {
msg='<row r="'+index+'">'
for(i=0;i<data.length;i++){
var key=data[i].key;
var value=data[i].value;
msg += '<c t="inlineStr" r="' + key + index + '">';
msg += '<is>';
msg += '<t>'+value+'</t>';
msg+= '</is>';
msg+='</c>';
}
msg += '</row>';
return msg;
}
//insert
var addrows="";
exportData.each(function (item,index) {
var r1 = Addrow(index+4, item);
addrows=r1+addrows;
});
sheet.childNodes[0].childNodes[1].innerHTML = sheet.childNodes[0].childNodes[1].innerHTML+addrows;
}
Im using Jquery datatables to construct a table.
My requirement is like below
This is not a static table, and we are rendering it using json data. Here I'm, rendering the rows dynamically using "aoColumns".
Is there any way to use rowspan so that the cells (1,2,David,Alex) can be spanned.
Does datatables support this kind of table ?
Datatables does not support this kind of grouping out of the box.
But, as in many cases, there is a plugin available.
It is called RowsGroup and is located here: Datatables Forums. A live example is also included.
If you change the JS part in this example to the below you will have your desired output presented to you in the output window.
$(document).ready( function () {
var data = [
['1', 'David', 'Maths', '80'],
['1', 'David', 'Physics', '90'],
['1', 'David', 'Computers', '70'],
['2', 'Alex', 'Maths', '80'],
['2', 'Alex', 'Physics', '70'],
['2', 'Alex', 'Computers', '90'],
];
var table = $('#example').DataTable({
columns: [
{
name: 'first',
title: 'ID',
},
{
name: 'second',
title: 'Name',
},
{
title: 'Subject',
},
{
title: 'Marks',
},
],
data: data,
rowsGroup: [
'first:name',
'second:name'
],
pageLength: '20',
});
} );
Here is a screenshot of the result:
I tried the RowsGroup plugin, but it achieves this just by hijacking the DataTables sort mechanism. If you tell it to group a given column, what it does for you is basically to apply a sort to that column that you can't turn off. So, if you want to sort by another column, you can't. That didn't work in my application.
Instead, here's a working fiddle for a recipe that allows you to achieve this result:
https://jsfiddle.net/bwDialogs/fscaos2n
The basic idea is to flatten all of your multi-row data into a single row. Content in your 2nd, 3rd, etc. rows are stored as a hidden <script> template tag within your first row.
It works by using DataTables' drawCallback function to manipulate the DOM once DataTables has rendered it, without confusing DataTables by having to try parsing rowspan cell content.
Since this modifies the DOM after DataTables has done its magic, your multi-row sections will stick together even with pagination, searching, and sorting.
Cheers.
add a below code and modify according to your requirement
$(window).on("load",function() {
MakeRows();
addRowspan();
$(".paginate_button").on("click", function() {
MakeRows();
addRowspan();
});
});
function MakeRows() {
var tmp_tbl = $("#dashboardDetails");
var _l = tmp_tbl.find("tr");
var _td = "",_t_td = "", old_txt = "",_t_txt = ""; _tr_count = 1;_tr_countadd = 1;
for(i = 0;i< _l.length; i ++) {
_t_td = tmp_tbl.find("tr").eq(i).find("td").eq(0).find("span");
_t_txt = $(_t_td).text();
_t_txt = _t_txt.replace(/\//,"_");_t_txt = _t_txt.replace(/\//,"_");
if (_t_txt.length > 0) {
if(_t_txt != old_txt) {
if($(_l).eq(i).hasClass(_t_txt) == false) {
_tr_count = 1;_tr_countadd = 1;
$(_l).eq(i).addClass("" + _t_txt + "").addClass(_t_txt + "_" + i);
}
old_txt = _t_txt;
} else {
_tr_count = _tr_count + 1;
if (_tr_countadd == 1) {
$(_l).eq(i).addClass("" + _t_txt + "").addClass(_t_txt + "_" + i)
.addClass("hiddenClass").addClass("maintr").attr("trcount", _tr_count).attr("addedtrcount", "maintr");
_tr_countadd = _tr_countadd + 1;
} else {
$(_l).eq(i).addClass("" + _t_txt + "").addClass(_t_txt + "_" + i)
.addClass("hiddenClass").attr("trcount", _tr_count)
}
}
}
_t_td = "";
}
}
function addRowspan() {
var t_txt = "";
var _alltrmain = $(".maintr");
var _h_td = ["0","10","11","12","13"];
for (i = 0; i <= _alltrmain.length; i ++) {
for (j = 0; j <= _h_td.length; j ++) {
t_txt = $(_alltrmain).eq(i).attr("trcount");
$(_alltrmain).eq(i).prev().find("td").eq(_h_td[j]).attr("rowspan", t_txt);
}
}
}
What I want to do: I want to display a diagram using Highcharts and the best code style.
Problem: My code is unreadable / hard to debug because I store it within variables.
Okay I have a Javascript-Object containing all the information I need for later use (categories, y axis value and the series itself which is split into positive, neutral and negative).
var testDia =
{
name : 'Testname',
'chartCategories': ['Golf', 'Polo', 'Passat'],
'chartSeries':
{
'positive': [
{y:341, url:'http://golf.com?q=positive'},
{y:487, url:'http://polo.com?q=positive'},
{y:180, url:'http://passat.com?q=positive'}
],
'neutral': [
{y:12, url:'http://golf.com?q=neutral'},
{y:3, url:'http://polo.com?q=neutral'},
{y:9, url:'http://passat.com?q=neutral'}
],
'negative': [
{y:222, url:'http://golf.com?q=negative'},
{y:115, url:'http://polo.com?q=negative'},
{y:321, url:'http://passat.com?q=negative'}
]
}
}
My approach is to loop over the categories and add positive, neutral and negative to seperate strings which I evaluate later on in the highcharts-setup.
var allPositiveData = '';
var allNeutralData = '';
var allNegativeData = '';
for(var i=0; i < categories.length; i++) {
var diaPositive = series['positive'][i]['y'];
var diaNeutral = series['neutral'][i]['y'];
var diaNegative = series['negative'][i]['y'];
urlPositive = series['positive'][i]['url'];
urlNeutral = series['neutral'][i]['url'];
urlNegative = series['negative'][i]['url'];
allPositiveData += "{'y': " + diaPositive + ", 'url': '" + urlPositive + "'}, ";
allNeutralData += "{'y': " + diaNeutral + ", 'url': '" + urlNeutral + "'}, ";
allNegativeData += "{'y': " + diaNegative + ", 'url': '" + urlNegative + "'}, ";
} // end of loop
allPositiveData = eval( "[" + allPositiveData.slice(0, -2) + "]" );
allNeutralData = eval( "[" + allNeutralData.slice(0, -2) + "]" );
allNegativeData = eval( "[" + allNegativeData.slice(0, -2) + "]" );
Highcharts-setup
newChart = new Highcharts.Chart({
chart : {
renderTo : 'container',
type: 'column'
},
[...] // skipping the rest of the setup
series: [
{
name: 'Positive',
data: allPositiveData
}, {
name: 'Neutral',
data: allNeutralData
}, {
name: 'Negative',
data: allNegativeData
}]
});
I figure there are a few ways to achieve what I want but I want to know a better (maybe object orientated) solution.
http://jsfiddle.net/x8455/
I think you are trying to do something what you already have done.
You want to get display three series from your JSON, for respective categories, then let's to that:
Your code:
var categories = testDia['chartCategories'];
var series = testDia['chartSeries'];
Great! Now use that variables:
newChart = new Highcharts.Chart({
chart : {
renderTo : portletContainer,
type: 'column'
},
...
xAxis: {
categories: categories,
labels: {
rotation: -45,
align: 'right',
}
},
...
series: [{
name: 'Positive',
data: series.positive // testDia.chartSeries.positive is the same
}, {
name: 'Neutral',
data: series.neutral
}, {
name: 'Negative',
data: series.negative
}]
});
And working demo: http://jsfiddle.net/x8455/1/
Here's how you should do it.
var allPositiveData = []; // You want an array, so start off with an array.
for(var i=0; i < categories.length; i++) {
var diaPositive = series['positive'][i]['y'];
urlPositive = series['positive'][i]['url'];
allPositiveData.push({'y':diaPositive, 'url':urlPositive}); // Add the element to the array.
}
That's all there is to it. Your Highcharts-setup piece of code can remain the same.
To make the sample a little shorter, I only edited the code for the positive data, the rest is the same, just a different name.
I would like to dynamically build a page from 2 hashes (in my example c and d).
var c = {
cluster_1 : { list_datasets: [ "a", "b", "c"]},
cluster_2 : { list_datasets: [ "b", "c"]},
};
var d = {
a : { title: "A", content: "aaaaaaaaaaaaaa"},
b : { title: "B", content: "bbbbbbbbbbbbbb"},
c : { title: "C", content: "cccccccccccccc"},
};
so that I first get the list of clusters, and then by clicking on the cluster, I get the list of their respective content. This works fine until here.
But now if I want to go a step further end by clicking on each dataset, I would like to have the dataset description. The jquery selection operation $('#a') is empty and nothing is shown. Here a little standalone example that shows the problem
Thanks a lot for you help or any information on that topic.
Kind regards
Antoine
Since these elements are created dynamically, you have to use delegate event handler like
$(document).on('click', '#'+key, function(event){
$("aside").html(value.content);
});
JSFiddle
Your problem is that you call second each
$.each(d, function(key, value){ ..
when there are no elements printed on the page.
Elements get printed only when you click on any of clusters. So you should wrap second each with a function e.g.
function getValues(){
$.each(d, function(key, value){
$('#' + key).each(function(){
console.log(value.content);
});
});
};
and call it at the end of click function
$('#' + cluster).click(function( event ) {
var content_list = "<ul>";
for (var i = 0; i < value.list_datasets.length; i++) {
var dsName = datasetName = value.list_datasets[i];
if(d.hasOwnProperty( datasetName ) ) {
var datasetName = d[datasetName].title;
}
content_list = content_list + "<li><a id='" + dsName + "' href='#foo'>" + datasetName + "</a></li>";
}
content_list = content_list + "</ul>";
$("section").html(content_list);
getValues();
});