jqGrid - Insert custom HTML into cell
Asked Answered
I

1

7

I am trying to convert a plain old html table to a jqGrid. The old table has a column containing tags which are constructed using an unordered list and list items.

Here is an example (jsfiddle) of the table before and the jqGrid after.

In this example I am using a custom formatter which uses jQuery Templates to construct DOM elements and then the formatter returns the $.html() from the resulting DOM elements.

function getTagCellContents(cellvalue) {
    var domitems=$("#jqgrid-tag-list-item").tmpl({tags: callvalue});
    return domitems.html();
}

The problem I had with this is that whitespace included in the resulting html causes the rows to be too high. This also results in awkward "Title" attributes on the cells.

Does the jqGrid provide an API for inserting DOM objects directly into the cell rather than by returning text from the custom formatter? What is the best practice for placing customized html into a jqGrid cell?

Instinct answered 10/9, 2013 at 23:59 Comment(0)
F
8

I find your question very interesting and so +1 from me for the question.

The main understanding problem with usage of custom formatter is: it required that your callback function return HTML fragment as string. The benefit of it is good performance, which one can see mostly on the large grid. If you works with DOM elements and uses constructs like domitems.html() you will have not so good performance.

So first of all I would recommend you to use $.template function of jQuery Templates. It allows you to work with strings without usage of DOM. The answer for example describes the main idea of the modification of your code.

To fix your main problem I suggest just to remove \n and withespaces from the string. I am not RegEx professional so I suggest the following quick and dirty solution:

// Create and cache a named template function
$("#jqgrid-tag-list-item").template("cellContents");
var tmpl = $.template("cellContents"); // template function

function getTagCellContents(a) {
    var strings = tmpl($, {data: {tags: a}}); // array of strings
    return strings.join('')
               .replace(/\n+/g,'')
               .replace(/\s+/g,' ')
               .replace(/> </g,'><');
}

Your jsfiddle demo will be the following after such modification.

Father answered 11/9, 2013 at 9:44 Comment(7)
Oleg, is it possible to add a new method to jqGrid API that actually append a DOM or jQuery object to a cell? I understand that using HTML is faster but sometimes there's no equivalent HTML for a DOM. For example, I want to insert a button with a custom eventListener. I can't do <button onclick='doSomething()'>Click Me</button> because my doSomething() is a private function and not accessible by HTML. Thanks!Adown
@LeiZhao: The memory used by web browser will be increased on setting of every separate onclick event handle. click supports event bubbling: if no event handle exist on <button> the click can be handled by the parent of the <button> and by the parent of the parent and so on. Look at the answer, this one, this one which provides example of usage beforeSelectRow or onCellSelect. If you will still have opened questions you can ask new question.Father
Oleg, thanks for your suggestions. However, in many case, I still need to actually insert/access/manipulate the DOM. The click event was just an example. Sometime it's more than that. For example I need to insert a native <select> tag and use selectmenu() to replace it with the jQuery UI widget when user clicks on a button outside jqGrid, or append a custom tooltip widget, or play a jQuery UI effect, or something like that. Right now I managed to select the td through the parent tr's id and the position of the td (something like grid.find("tr#rowId td:nth-of-type(3)")), butAdown
but it's not very readable and if the order of columns change I'll need to find and update all these numbers.Adown
@LeiZhao: You can manipulate DOM inside of loadComplete for example, but you should understand that if you change one element on the page the position and some properties of all elements on the page could need be recalculated. It's so named reflow. So if you modify x elements on the page which contains y elements the complexity of the operation is xy* instead of just x. You can ask new question where you detailed describe your problem and I could try to help you.Father
After long time working again on jqGrid with similar requirement, as in past @Father your answer saved my lots time in searching.Brenda
@Shaggy: Thank you for your comment! I like that my old posts are still helpful.Father

© 2022 - 2024 — McMap. All rights reserved.