didCellParse does not return cell - jspdf

I'm trying to center a row. My <td> has colspan across the table.
I have a data tag in the <td> because I have dynamic subheaders in the tables. With willDrawCell and didDrawCell I can access the cell.raw property and check the data tag to apply the style.
When I use didCellParse the CellHookData has cell as undefined.
With the willDrawCell and didDrawCell, I can alter the halign property, but it DOES NOT render in the center of the row in pdf.
didParseCell: data => {
if($(data.cell.raw).data('subhead') == true){
data.cell.halign = 'center';
}
}
With didParseCell I receive an error, because cell is undefined.
https://codepen.io/lightningmd/pen/gOOaezM
This code pen is using willDrawCell. You can see the subheader is found, and the cell.styles.halign is applied. Just change to didParseCell for the error.

You need to set the styles on the cell styles object, not the cell: data.cell.styles.halign = 'center'.
Seems there also is a bug where didParseCell is called with a null value for data.cell when there are colspans/rowspans. All in all, this should work:
didParseCell: data => {
if (data.cell && $(data.cell.raw).data('subhead') == true) {
console.log('Subheader Found;')
data.cell.styles.halign = 'center';
}
}

Related

jsPDF Autotable change cell color for negative values

I’m using jsPDF Autotable to generate a PDF from an HTML table. The TD element contains an ID that populates the cell with a variable . Everything works fine, but I wanted to set the textColor to red for negative values. I can’t find an example of how to achieve this?
EDIT:
I solved making the bottom row of a table red when the values are negative using a hook...
drawCell: function (cell, data) {
if (summary_balance_weekly <0) {
if (data.row.index === data.table.rows.length - 1) {
doc.setTextColor(255,0,0);
}
}
}
For the latest version of jspdf-autotable, createdCell function is deprecated, so use didParseCell function. below is the example to change color if data in a cell is negative
didParseCell: function (data) {
if(data.section === 'body' && data.cell.raw < 0){
data.cell.styles.textColor = "red";
}
}
fillColor and textColor both accept RGB array. So the sample code will look like this:
createdCell: function(cell, opts) {
if (opts.column.index >= 1) { // count startrs from 0
// cell.raw contains the cell data
cell.styles.fillColor = [216,78,75]; // random color
cell.styles.textColor = [58,121,152];
}
}

How to maintain tableview scroll to stop reusing cell

I have multiple sections in tableview. I have multiple questions and multiple answers of each question. In multiple answers, I have one option and that is other (option). when I select the button of other, then it shows the text field for advice. Now i need to maintain the data of text field and that selected option's (Other) text when scrolling in tableview.I am using below code for all answer.
if (indexPath.section == 2)
{
let cellidentifier="cell3"
let cell=tableView.dequeueReusableCell(withIdentifier: cellidentifier,for:indexPath as IndexPath) as! TextfieldTableViewCell
let object_3:AnswerBaseClass = arrobject_answer[0][indexPath.row]
//print("arrobject is\(arrobject_answer[0][indexPath.row])")
if object_3.answer == "O"
{
// cell.lbl_answer.isHidden = true
cell.btn_selected.isHidden=true
//cell.lbl_answer_height.constant = 0
cell.Other_textfield.tag = 101
cell.Other_textfield.borderStyle = .line
cell.Other_textfield_top.constant = -30
cell.Height_2.constant = 30
}
else
{
cell.lbl_answer?.text = object_3.answer!
cell.Other_textfield_top.constant = 12
cell.Height_2.constant = 0
cell.lbl_answer.isHidden = false
cell.btn_selected.isHidden=false
if answer_main_data[0][indexPath.row] == true
{
cell.lbl_answer.tag = indexPath.row
cell.btn_selected.isSelected=true
if cell.lbl_answer.text == "Other"
{
for subview in cell.contentView.subviews
{
subview.removeFromSuperview()
}
if arrOtherTextfield_2.indices.contains(indexPath.row)
{
cell.addSubview(arrOtherTextfield_2[indexPath.row])
}
else
{
cell.Other_textfield.tag = 1100
cell.Other_textfield.borderStyle = .line
cell.Height_2.constant = 30
arrOtherTextfield_2.append(cell.Other_textfield)
}
}
else
{
cell.Height_2.constant = 0
}
}
else
{
cell.Other_textfield_top.constant = 12
cell.btn_selected.isSelected=false
cell.Height_2.constant = 0
}
}
cell.Other_textfield.borderStyle = .line
return cell
}
You will have to retain (store in some dictionary) the data entered in textfield, otherwise it will be lost when you scroll table and cell is reloaded. If you don't want to retain then you should use scroll view instead of table view. In scrollview it will not redraw UI even if you scroll up and down.
You need to separate UI and data. You embed data into your cell and when cells are reused, you lost data.
You can do 2 things:
Create a ViewModel class which contains data of cell: text, color, etc. Of course you need to update your ViewModel as you receive input You can google "MVVM pattern" for more information. Even if your cell is reused, your data is safe in ViewModel object.
You can keep your cells in an Array so that they won't be reused.

Highlight/ change background color of cell using another data

I have 2 columns like TPF and TPF_FLAG which i get from my rest service. TPF_FLAG will be 0 or 1 which indicates that should i change the background color of TPF cell or not. If it 1 that TPF cell background should be red. How do i do this?
You can use the renderer on the column like this:
{
text: 'TD',
dataIndex: 'TPF',
renderer: function (value, metaData, record) {
if(record.get('TPF_FLAG') == 1){
metaData.tdStyle = 'background-color: red';
}
return value;
}
}
And note, that the value you return from the renderer will be shown in the column.
Also, you can look at the docs for more things you can do with renderer.

Odd behavior with UITableView in Swift

I have a custom cell with two labels and a image. I receive some data from internet in Json. Everything works fine; every cell fills with the correspondent data. I've added a new label that has to be filled just like the other ones. This is the data:
let cell = tableView.dequeueReusableCellWithIdentifier("friendCell") as! friendCell
cell.friendPicture?.image = newImageUser
cell.friendName.text = "#\(theName[indexPath.row])"
if repliesNumber[indexPath.row] == "0"{
cell.repliesNumber.textColor = UIColor.redColor()
}
else{
cell.repliesNumber.textColor = UIColor(patternImage: UIImage(named:"backgroundPattern")!)
}
if AttachedImage[indexPath.row] != ""{
cell.backgroundColor = .orangeColor()
}
For testing I've made to be colored the first two cells. My issue is that the fist two cells get colored, but if I scroll down, every two, three, four cells (depending on the device -device height I guess-, another two cells get colored too.
It's odd/weird because the rest of labels work fine.
Where should I start looking?
If I print the json data I receive everything is okay
Here is a gif:
GIF
Basically my problem is that when I scroll down the data disappear but only from a label, the rest of labels and images doesn't.
It's not very clear from your code which are the cells that are "colored". Is it from the orangeColor() condition ?
Anyway, UITableViewCells in an UITableView are reused, which means you are given them in the exact same state you left them. This is why, if you don't reset your backgroundColor, they still are orange as you scroll.
So basically, whenever you do something in a certain condition in a cell, don't forget to restore its state when the condition is not met. In your case, this gives :
// cellForRowAtIndexPath {
if itemIsMultimedia() {
cell.Multimedia.text = "it's multimedia"
cell.Multimedia.hidden = false
}
else {
cell.Multimedia.text = ""
cell.Multimedia.hidden = true
}
here #aimak
if AttachedImage[indexPath.row] != ""{
cell.Multimedia.text = "It's multimedia"
}
else{
cell.Multimedia.hidden = true
}

Handsontable Password Renderer

I tried to apply PasswordRenderer to a specific row and column based on the value of that row.
So my custom renderer looked like this -
function firstRowRenderer(instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.PasswordRenderer.apply(this, arguments); }
However the problem I face is, while editing the cells, the field is no longer masked. Here is an example - http://jsfiddle.net/whxbv6xh/
If you try and edit the first row of that table, the values are not masked. Any ideas?
This "unmasking" of the field is what the PasswordRenderer is essentially all about. If you want to not be able to see the original values at all you have at least two options:
1.Convert the header row's values beforehand:
function renderAsPassword(password) {
return new Array(password.length + 1).join('*');
}
alert(['', 'Kia', 'Nissan', 'Toyota', 'Honda'].map(renderAsPassword));
2.Create a custom editor, extending the built-in PasswordEditor:
var PasswordEditor = Handsontable.editors.PasswordEditor.prototype.extend();
PasswordEditor.prototype.getValue = function() {
return renderAsPassword(this.TEXTAREA.value);
};
PasswordEditor.prototype.setValue = function(newValue){
this.TEXTAREA.value = renderAsPassword(newValue);
};

Resources