Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3 and links in the table #355

Closed
vita10gy opened this issue Oct 7, 2015 · 47 comments
Closed

v3 and links in the table #355

vita10gy opened this issue Oct 7, 2015 · 47 comments

Comments

@vita10gy
Copy link

vita10gy commented Oct 7, 2015

I'm trying to upgrade from version 2 to 3 and I can't figure out why it's stripping links out of my tables.

In fact it seems like it's showing the user whatever it figures out to use as the value to sort by internally (including if given one via data-value, when the whole point of that USED to be to have one way that's easy to sort on, and one way that's better to read) This happens even on a column with data-sortable="false" set.

Am I missing something stupid?

@vita10gy
Copy link
Author

vita10gy commented Oct 7, 2015

Also this is a minor point, but I ran into a problem where I had to rename .pagination because foundation (zurb) already provides that class. You have foo* in many places, might be good to keep that up on all classes.

@mlanser
Copy link

mlanser commented Oct 10, 2015

I see the same issue as @vita10gy ... but it does 'flash' the links briefly during a page refresh.

@GaryStanton
Copy link

Same here - not used FooTables before; am I right in thinking this did not happen in previous versions?

@vita10gy
Copy link
Author

In previous versions it would sort based on the visible content of links, not the exact HTML, so presumably it stripped HTML behind the scenes, and that's a good thing. It would sort on one version of the thing while showing another.

This version seems to go out of its way to show the "behind the scenes" version of it. It even shows what you set in data-value which was previously explicitly there for "sort on this while showing this other thing".

@craigmatthew412
Copy link

I've noticed it is 'sanitizing' any HTML in the cells. It's removing any span and br tags I am trying to use as well.

UPDATE: FooTable.Column.parser checks if cell is a jQuery Element by using the utility function FooTable.is.jq, and if TRUTHY will pull data-value if present or calls jQuery.text() to pull the cells contents. You can write your own column parser that uses jQuery.html() instead if you don't want your links stripped out. It isn't very clear from the documentation that is uses .text() to strip it's contents, I had to view the source after scouring the docs.

@FraOre
Copy link

FraOre commented Oct 22, 2015

Can someone resolve it?!

@rickgregory
Copy link

Thanks for the detective work Craig. I'd still consider this a bug since it's altering data without an obvious way to tell it not to do so. I can also see cases for doing this so I'll create a new ticket as a feature request to add a parameter that controls this and to ship both parsers in the base plugin.

@vita10gy
Copy link
Author

You also want it to be sure it sorts on text() but shows html()

@sturze
Copy link

sturze commented Oct 27, 2015

same here... has anybody yet found a workarround? older versions? is it going to be fixed?

@FraOre
Copy link

FraOre commented Oct 27, 2015

+1

@graceWeareduo
Copy link

I've had this same issue. If you take the js and css from the demo pages links will work:
http://fooplugins.com/footable-demos/

@vita10gy
Copy link
Author

Is that a workaround or the solution? Is this intended behavior? Should we have to define a parser/something to get basically "show people what I put in there to show?"

Edit: a post seems to have gone missing.

@FraOre
Copy link

FraOre commented Oct 30, 2015

graceWeareduo that is version 2... Not 3...

Nobody can remove this HTML sanitizing when is not necessary?

@antonsarov
Copy link

Well this is kind of a show-stopper because links in cells is fairly common. Writing an own parser would be an overkill for such functionality (which should be provided out-of-the-box as a config option) - but even this is better than nothing. However I am missing the documentation about this...

@vita10gy
Copy link
Author

vita10gy commented Nov 3, 2015

I'm just holding out on hearing from the people in charge. I have to believe this wasn't intentional, because it even happens on columns you're not even sorting.

Ultimately, I suppose you could argue that defining something when you want to show the people something different that what you're sorting on is the same basic issue as before, just reversed. (When we wanted to tell it to sort on something besides what we're showing.) That would be a kind of large about face, though, even were it a 6 of one half dozen of the other situation.

At the very very very least there should indeed be a built in parser to say "there's HTML in there I want shown"

I'm sure one of us could figure it out, but I'd like to hear what's up from the head people. (If for no other reason than it's mostly for naught if they don't want to, or aren't around to, merge it.)

People generally don't accept bug fixes on things they consider to be features. :)

@ghost
Copy link

ghost commented Nov 3, 2015

If you load datas via JSON/AJAX (like on demo page V.3) or create JSON strings with PHP no tags are stripped inside TD.

My workaround:
If I use "static" tables first buit via PHP I add a custom attribute data-foohref="http://andsoon" to TDs and build links inside TD via JQuery after initialsing footable. Set them after text as link button because of sorting issues. Didn't test if second necessary.

@rickgregory
Copy link

@bertmert - and that's a ton of work to be able to preserve links inside of a cell. I get the sorting issue, but not all applications rely on the column with links being sorted (mine doesn't, I want to display a class schedule with a cell that has a registration link in it). At the least, it feels like there should be a parameter to allow a cell to not be sanitized.

@ghost
Copy link

ghost commented Nov 3, 2015

@rickgregory
Yes, I know. It should be fixed but at the moment (V.3.0.1) loading datas via JSON is the easiest and most reliable solution. It's not that complicated to create the JSON-Strings for rows and columns with PHP from an array. I know, too, no hint inside documentation and lots of examples concerning HTML are wrong there (#370).

So, temporary workarounds or version 2 ;-)

@antonsarov
Copy link

This is the workaround I am using (beware that I am not a JavaScript programmer - so it works but it is not beatiful)

The table column gets a custom parser where the name of the parser correspond to a JavaScript function
<th data-sort-ignore="true" data-parser="myParser">Action</th>

The JavaScript function should be defined before the HTML table is initialized with $('#myTable').footable();. The function receives one parameter which is the cell element and has to return the representation of this element - either HTML, null for nothing, some String representation etc.

<script>
   function myParser(valueOrElement) {
       var innerHTML = valueOrElement.context.innerHTML;
       // check for opening bracket which symbols some HTML data
       if (innerHTML.contains('<')) {
           return innerHTML;
       } else {
           return null;
       }
    }
</script>

@sturze
Copy link

sturze commented Nov 11, 2015

cool thing! worked! Thx! but i had the issue, that in case it wasnt a link it returned nothing... so i changed it to:

<script>
   function myParser(valueOrElement) {
       var innerHTML = valueOrElement.context.innerHTML;
       // check for opening bracket which symbols some HTML data
       if (innerHTML.contains('<')) {
           return innerHTML;
       } else {
           return valueOrElement.context.innerHTML;
       }
    }
</script>

EDIT: AAAHHH! just found out that this breaks all footable functionallity in Chrome and Edge (IE not tested) Error in Edge is:

FooTable: unhandled error thrown during initialization. TypeError: Object doesn't support property or method 'contains'
footable.js (1705,6)
"FooTable: unhandled error thrown during initialization."
{
[functions]: ,
proto: { },
description: "Object doesn't support property or method 'contains'",
message: "Object doesn't support property or method 'contains'",
name: "TypeError",
number: -2146827850,
stack: "TypeError: Object doesn't support property or method 'contains'
at myParser (http://server/site/:66:8)
at Anonymous function (http://server/site/js/footable.js:840:5)
at define (http://server/site/js/footable.js:914:4)
at Anonymous function (http://server/site/js/footable.js:3835:3)
at Anonymous function (http://server/site/js/footable.js:662:7)
at construct (http://server/site/js/footable.js:884:4)
at Anonymous function (http://server/site/js/footable.js:679:5)
at createCell (http://server/site/js/footable.js:1242:4)
at Anonymous function (http://server/site/js/footable.js:1437:5)
at F.arr.map (http://server/site/js/footable.js:227:4)"
}

@FraOre
Copy link

FraOre commented Nov 12, 2015

For me the script doesn't work when there is pagination or filter...

I think is absurd this bug in a so strong plug-in...

Hoping someone can fix it...

@FraOre
Copy link

FraOre commented Nov 17, 2015

function html_parser(element) {
return element.context.innerHTML;
}

this one works...

@craigmatthew412
Copy link

I basically copied the source function and put it on the window (since I am browserifying my app bundle, needed to be accessible by FooTable), and replaced the .text() call with .html(). Works great for my application...might not work for everyone else' needs however.

/**
 * @desc Custom Column Parser for FooTable.  Instead of using jQuery.text() to parse cell contents, it uses jQuery.html()
 * @param {Object} valueOrElement - element or value to be parsed.
 * @returns {*}
 * @constructor
 */
window.HTMLParser = function(valueOrElement) {
    if (FooTable.is.jq(valueOrElement)) {
        var valOrEl = valueOrElement.data('value') || valueOrElement.html();
        return valOrEl;
    }
    if (FooTable.is.defined(valueOrElement) && valueOrElement !== null) {
        var valueOrElementString = valueOrElement + '';
        return valueOrElementString;
    }
    return null;
};

@rdbrazil
Copy link

+1 for a final fix

@vita10gy
Copy link
Author

Agreed. Until we hear from @steveush and co, I vote we stop posting workarounds.

Making it superficially leave the HTML alone is a trivial change, but then it sorts on the HTML and not the visible content.

The parsers and seem like they are just too much work for something that could "just work", if no other way than some common parser we don't actually have to write.

If that's what it comes to then c'est la vie, but I have a feeling it wasn't intentional. Posting workarounds can be problematic because the author almost never knows the implications of the change, only that it makes it look like the one thing works, but then before you know it all sorts of passers by implement it.

Same type of thing that makes it so everything on the stackoverflows of the world end up being the blind leading the blind. Where the top answer is almost always among the first answers and the first answer is often from someone who just found a solution from themselves that isn't battle tested. Then, by the time someone comes along with the "No! Don't do that! It's a massive security issue!" comment the wrong answer has 203 upvotes and the right answer is buried forever.

There might also be a really good argument for why it is this way.

@adamgins
Copy link

adamgins commented Dec 8, 2015

Hi, was there any movement on this issue?

@steveush
Copy link
Member

steveush commented Dec 8, 2015

Hi, in 3.0.2 there is now an HTML column type available which should leave HTML content in cells untouched. To make use of this simply set the data-type attribute on the column to "html".

@steveush steveush closed this as completed Dec 8, 2015
@sturze
Copy link

sturze commented Dec 8, 2015

Nope.... not fixed! just tested! if i add a link in a cell it works, if i add a cell without, just with text in the next line not....

line configured as data-type "html"

<td> <a href...> </a> </td>   #works
<td> asdfasdf </td>              # works not... shows just a empty cell

####edit:
workarround for this version:

in mixed columns create a tag (for example <n></n>) not <p>(seems not to scale well on lower resolutions)

like:

<td> <a href...> </a> </td>   #works
<td> <n> asdfasdf </n> </td>  #works

@dave-buzzy
Copy link

Yep - seconding @sturze 's observation, just found the same issue. Temporary workaround is to make all columns to data-type="html" (since we won't know in advance whether a cell will contain a link or other markup), then wrap every cells' content in a div by default. But would prefer not to need the extra markup.

<td>
    <div><a href="...">...</a></div>
</td>
<td>
    <div>8:30 - 2:30</div>
</td>

@jhall39
Copy link

jhall39 commented Dec 8, 2015

I can verify we have the same issue here.

@sturze
Copy link

sturze commented Dec 8, 2015

AND it also not fixed:
HTML breaks sorting! still seems to sort html not text...

@jhall39
Copy link

jhall39 commented Dec 8, 2015

use data-sort-value on your cell and set it to your value without the html? That's what I'm doing to sort a date field since setting the column to data-type ='date' doesn't seem to work. I format the value for the cell contents and then set data-sort-value to the epoch timestamp.

@steveush
Copy link
Member

steveush commented Dec 8, 2015

Hi, the fix is a fairly simple one and I will push it to the repo shortly in 3.0.3. Basically in the HTMLColumn#parse method I just need to change the code to use jQuery's .contents() method instead of .children() which excludes text nodes. As for the sorting of HTML columns @jhall39 is correct. You will need to provide a data-sort-value attribute to specify the value to use for sorting otherwise the column is indeed sorted by HTML as it's an HTML column that could contain anything. This is the exact reason I added the data-sort-value attribute in this update. The same can be said for filtering, you can provide custom values for HTML columns using the data-filter-value attribute.

@sturze
Copy link

sturze commented Dec 8, 2015

thanks for the quick answer! pretty cool to hear it can be fixed easily...
how han i define a data-type html column with html and text mixed to sort by text? is it documented anywhere? or can anybody give a short example?

@steveush
Copy link
Member

steveush commented Dec 8, 2015

Hi, I finally realized what you meant by sorting by HTML, it should have been sorting by the HTML string value but it was sorting by the actual DOM elements themselves. Apologies, that was a misunderstanding on my part and a bug. In the 3.0.3 update I have updated the HTMLColumn object to override the default sortValue function and use the cell's contents HTMLString as the default sort value. I also added in an HTML column specific data attribute to allow you to use the text value of a cell's contents instead of the HTML string by simply appending data-sort-use="text" to the HTML columns header cell, or through the JS options by using the property sortUse: "text".

<table class="table">
  <thead>
    <tr>
      <th data-type="html" data-sort-use="text">HTML Column</th>
    </tr>
  </thead>
</table>

Using the above "text" value a cell with the contents of Some text and <a href="#">a link</a>. would have a sortValue of Some text and a link.. Basically the result of calling jQuery's .text() function on the cell.

If this does not resolve your issue you can always override the default HTMLColumn#sortValue function with one of your own and return whatever value you like.

FooTable.HTMLColumn.extend('sortValue', function(valueOrElement){
 // parse the parameter and return what you need, take a look at the default functions to get an idea of what is required.
});

@steveush steveush reopened this Dec 8, 2015
@steveush
Copy link
Member

steveush commented Dec 8, 2015

Fixed in 3.0.3

@steveush steveush closed this as completed Dec 8, 2015
@sturze
Copy link

sturze commented Dec 9, 2015

just tested! done! works fine without any overrides. Thank you very much!

an other question to datatypes and this time combined search:
is it possible to search/filter in one column containing Symbols for a specific class ( in example first-aid) or id? Is there something like search-data-type?

for example:

<td style="display: table-cell;">
<i class="fa fa-medkit first-aid"></i>
</td>

@dave-buzzy
Copy link

@sturze - in your context, isn't that cell basically empty? There is no text or data value attached to the cell or its contents, simply an empty html container. Wouldn't this be a case for using footables' data-value on the cell to give it an actual value, then searching/sorting on that?

Bonus points: You could improve accessibility and get it to work by adding a non-rendered label inside the cell next to the icon to describe the value (for instance using something like Bootstrap's .sr-only class to stop the label being visible but still available to the dom and readable by screen-readers or other assistive technology).

Oh, and @steveush, thanks for the updates! Appears to be working fine again :)

@sturze
Copy link

sturze commented Dec 9, 2015

@dave-buzzy - yup, basically empty, i forgot to tell that i'm using "font-awesome" for my symbols...
http://fortawesome.github.io/Font-Awesome/

the problem is, if i add content the cell width changes and i dont want to waste space... i need jst this symbols!
i just want to add something to filter rows with that specific symbols...

in my case first aid contacts (different people) in a phonelist. So i thought it would be great to search (for example) for "first-aid" and it filters just that specific lines (and that's why i defined that class in the example above)

@steveush
Copy link
Member

steveush commented Dec 9, 2015

@sturze & @dave-buzzy you can use the data-filter-value attribute to provide completely different values for filtering a cell to what is displayed within the cell. For example you can specify the filter value like I did below and people would be able to search using any of those terms.

<td data-filter-value="first-aid help rescue 911">
  ...
</td>

In this case specifying data-value would not work as this attribute overrides the actual value of the cell and you would loose your original contents when the table is redrawn.

@steveush
Copy link
Member

steveush commented Dec 9, 2015

@sturze also to make only a single column searchable you will need to define data-filterable="false" on all columns you do not want to search. The default works by allowing all columns to be searchable and you have to opt out.

@sturze
Copy link

sturze commented Dec 9, 2015

Perfect!!! thank you very much! data-filter-value was what i was searching for! Done!

@gsurowiec
Copy link

I found solution for this problem.
Change line: 1293

if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)) return $(valueOrElement).data('value') || $(valueOrElement).text();

to:

if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)) return $(valueOrElement).data('value') || $(valueOrElement).html();

@sturze
Copy link

sturze commented Feb 25, 2016

already fixed?! no need to change code, just define the data-type... or am i wrong?

<table class="table">
  <thead>
    <tr>
      <th data-type="html" data-sort-use="text">HTML Column</th>
    </tr>
  </thead>
</table>

@Llewellynvdm
Copy link

Well this worked for me

<table class="table">
  <thead>
    <tr>
      <th data-type="html" data-sort-use="text">HTML Column</th>
    </tr>
  </thead>
  <tbody>
     <tr>
       <td><a href="" ><b>James</b></a></td>
     </tr>
   </tbody>
</table>

@hfishere
Copy link

Oh man, you saved my life..! Thanks a lot! @Llewellynvdm

Thanks for post @vita10gy

@pagimaxx
Copy link

Hi, Anyone knows, how do I execute a javascript function at the link? Like this example:

<a href="#" id="cmdAction" onclick="myFunc();">Click</a>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests