0

I use a standard function to retrieve an image within the system, as we have the binary in the database, this works good throughout the whole system.

Currently implementing jqGrid and have some issues to use the current structure as images don't show up and the jquery structure ($obj = $("<div>");) is not useable.

Now I try to implement to get the binary image, however it won't show up, when using a static url it works and image data is being retrieved.

 $.extend($.fn.fmatter, {
            getBinairy: function (cellValue, options) {
                //var object = $();
                var width = 50;
                var html = "";
                getImage(cellValue).success(function (data) {
                    $.each($.parseJSON(data.d), function (idx, obj) {
                        p_image = obj.img;
                        p_type = obj.type;
                        p_width = obj.width;
                        p_height = obj.height;
                    });
                    var _width = width / p_width;
                    var _height = _width * p_height;
                    html = "<img src='data:" + p_type + ";base64," + p_image + "' />";

                    //object = $("<img/>", {
                    //    src: "data:" + p_type + ";base64," + p_image,
                    //    width: width,
                    //    height: _height
                    //});
                    //object.append($img);
                });
                //var html = "<img src='img/test/20131027_132450.jpg' />";
                return html;
            },

As far I think the fn is loading the "html" too fast, I can't understand other reason, however have no idea how to avoid this.

Any help?

---UPDATE---

 var ip = "";
            var station = "";
            return $.ajax({
                type: "POST",
                url: "services/general.asmx/SendBinairy",
                data: JSON.stringify({ session: 'ed6d1cc6-82f9-46e8-91bb-eae341a771cf', ip: ip, station: station, id: id }), ///, _filter: JSON.stringify(_json) }),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                loaderror: function (xhr, status, error) {
                },
                success: function (data) { }
            });

---UPDATE---

"dataset": [
  {
    "id": 5,
    "suffix_type_id": 0,
    "sexe_type_id": 1146,
    "first_name": "Varvara",
    "middle_name": "",
    "last_name": "D",
    "full_name": "Varvara D",
    "company_name": "",
    "nickname": "",
    "birthday": "1983-12-18",
    "age": 31,
    "language_type_id": 6,
    "relation_type_id": 0,
    "job_status_type_id": 404,
    "nationality_type_id": 0,
    "last_online": "",
    "last_online_app_id": 0,
    "profile_image": 24,
    "profile_rating": 7.000,
    "number_contacts": 0,
    "number_applications": 0,
    "address_id": 0,
    "address_1": null,
    "address_2": null,
    "address_3": null,
    "number": 0,
    "add": null,
    "postal_code": null,
    "city": null,
    "city_type_id": 0,
    "latitude": null,
    "longitude": null,
    "state": null,
    "state_type_id": 0,
    "country_type_id": 0,
    "address_type_id": 0,
    "image": [
      {
        "file_id": 24,
        "binary": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIB

And this is how I add the data to the jqGrid

$("#" + grid_id).jqGrid({
                                        loadonce: true,
                                        type: "POST",
                                        url: "services/general.asmx/HelloWorld",
                                        postData: { q: session },
                                        datastr: colD,
                                        contentType: "application/json; charset=utf-8",
                                        datatype: "jsonstring",
                                        colModel: colM,
                                        rowNum: 10,
                                        rowList: [10, 20, 30],
                                        pager: '#' + grid_id,
                                        sortname: 'id',
                                        viewrecords: true,
                                        sortorder: "desc",
user3763117
  • 327
  • 1
  • 5
  • 18

1 Answers1

0

The function getImage is undefined in your code, but I still think that you've chosen wrong way for getBinairy formatter. I suppose that you makes asynchronous Ajax call to the server inside of the formatter. So the function getBinairy returns "" (the initial value of html variable).

I recommend you to change the format of cellValue - the format of data for the column which returned by filling the main grid. For example the data could be JSON encoded object {src:.., width:... , height:... } or {mimeType: ..., charset: ..., base64: ..., width: ... , height: ...} or some other. It's important just that the input data should be full and the formatter will be just produce <img> based on the data without any Ajax calls.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • The function getImage returns based upon the cellValue the correct binary data, however it returns outside of the scope of the success "". I use to solve this with binding gthe data to "object" as commented out which is a div and works. So what you purpose is to load all data when loading the grid data also load the image binary direct to avoid the ajax call? – user3763117 Sep 14 '14 at 10:19
  • @user3763117: Sorry, but I still not sure that I correctly understand what you do. The usage `.success(function (data) {... $.parseJSON(data.d) ...});` looks like making **asynchronous call** to the server which will be wrong. Do you makes `$.ajax` call inside of `getImage` or not? You should think about jqGrid custom formatter as **string formatter** you get `cellValue` string as input and it should return another string: HTML fragment which will be placed inside of grid cell (``) on the column. No DOM elements (`$("")`), No Ajax calls etc - just producing pure HTML string. – Oleg Sep 14 '14 at 10:31
  • Yes I do that call, this is why the html is not being filled I guess, the getImage is as the update in the question and returns just the data. As you say I realized that this is a string formatter and does not handle any Jquery objects. As you previous suggest to send the complete binary with in the request to build the grid I have some issues with this but might be the only solution as far I understand you, correct? – user3763117 Sep 14 '14 at 10:41
  • @user3763117: You can include `async: false` option in `$.ajax` call to make formatter working, but it will work **very slowly**. Why you fill first the grid with some `cellValue` in the column and then makes `"services/general.asmx/SendBinairy"` **for every cell of the column**? Round trip for the call takes a lot of time. Instead of that you should fill initial grid data with the information which provides `"services/general.asmx/SendBinairy"`. – Oleg Sep 14 '14 at 10:51
  • In this matter you correct, our system is being build upon view calls, the grid has different approach and should be build in direct. I aint a fan of async:false as you state it makes all so slow. I go back to workfloor to find the fitting solution and post it here ) – user3763117 Sep 14 '14 at 10:57
  • @user3763117: I strictly recommend you to read [the answer](http://stackoverflow.com/a/12519858/315935) and to view [the video](https://www.youtube.com/watch?v=ZHxbs5WEQzE) or [this one](https://www.youtube.com/watch?v=gqc88qWuiI4) about **reflow** in web browser. jqGrid build *full contain* of grid body (all rows) as **one html string** and then place it on the page as **one operation**. It describes *why* custom formatter works only with strings. Such way makes jqGrid working *very quickly* even in case of large number of rows. – Oleg Sep 14 '14 at 10:57
  • @user3763117: Please include an example in the next update. For example what value have `cellValue` of `getBinairy`? (what data you return in the column during main filling of the grid). What returns `"services/general.asmx/SendBinairy"`? Why you not fill the information directly in the main grid data? – Oleg Sep 14 '14 at 11:00
  • I will do this, now playing with good solution, post it later. The reason why not I use this function within the whole system which hardly uses grid and all images are being loaded upon user action, this is a different structure, so I am looking if I can make it fit within the system currently – user3763117 Sep 14 '14 at 11:27
  • Right now i am just building the colModel from JSON very simple and sthraight forward, the id of the image is in this JSON. however now I need to send the JSON data to the formatter function to generate the picture..... About generate this jqGrid on server side (I assume you ment this with building all rows) this will not work as we generate these grids on the fly and after use it will be destroyed otherwise I need to pre generate 100ths of these and will delay everything. Any advise how to get this image data into the grid visual? – user3763117 Sep 14 '14 at 16:43
  • Can I send the colD (data) for this row to the formatter so I can get the JSON image, generate the html string for the image and put this in the right column? – user3763117 Sep 14 '14 at 16:54
  • Typically one saved the data for img in the database. So you can just have a table with required `base64` data instead of *generating* it every time from binary images. You can event organize server response so that it have one part with embedded images which you reference in the main part: `{"imgs": {"id123": {"src": "...", "alt": "..."}, "id456": {"src": "...", "alt": "..."}}, "dataset": [{"img": "id123", ...}, {"img": "id456", ...}, {"img": "id123", ...}, {"img": "id456", ...}, ...]`. custom formatter getBinairy can use `imgs` part of the server response to decode `img` with ids – Oleg Sep 14 '14 at 16:57
  • In my case I see the problem in the way we construct this data as the source of this data is being retrieved based upon generation of the jqGrid, so the jqGrid is child to another "dataHandler(session).success(function (data) {" and the formatter is outside this dataHandler, and it will be impossible to get this data upfront as this will be thousends of images, good thing is that the images loaded here are very small 3-5kb but still.... – user3763117 Sep 14 '14 at 17:26
  • I placed the formatter within the "dataHandler" and this seems to work also let me see if I can solve my problem like this – user3763117 Sep 14 '14 at 17:33
  • @user3763117: Sorry, but I don't full understand the problem which you describe. I don't understand which `dataHandler` you mean and don't know the "nature" of the image which you need to format. It's unclear why the image or `dataHandler` could depend on session of the user. So I can't give you now any additional tips. – Oleg Sep 14 '14 at 17:51