Changing display type based on file type.

Changing display type based on file type.

classic12classic12 Posts: 228Questions: 60Answers: 4

Hy guys,

I am using the editor successfully ( amazed at how much you can do with it).

I am upload image / pdf / txt and xls files to my server.

I now need to show these in a datatable.

I use

"data": "web_path",
                        "render": function ( data) 
                        {

              return '<img src="'+'http://toolfolks.com'+data+'" style="height:50px;width:50px;"/>'
                        }

which is fine for images & pdf.

If the file is not image type how do I set the cell to show the filename and be downloadable. IE they click on it and it down loads.

Cheers

Steve Warby

Answers

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    Do you have the information telling you want the file type is in the row? If so, you can access that using the third parameter passed into columns.render. Then use a simple if condition to sent out the correct HTML.

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Thanks Allan,

    I'm nearly there.

    I am trying this approach.

     for ( var i = 0; i < dataReturned.length; i++) {
            var obj = dataReturned[i];
            console.log(obj);
            var fieldName;
            var fieldValue;
     
            for ( var key in obj) {
                fieldName = key;
                fieldValue = obj[key].toString();
                             if ( fieldName === 'web_path') {console.log(fieldName + '   ' + fieldValue);
                              var ext = fieldValue.substr(fieldValue.lastIndexOf('.') + 1);
                              if( ext === 'jpg'){
                              dataReturned[i].push(['Type','Image']);
                              var dataPoint = { 'Type': 'Image' };
                              dataReturned.push(dataPoint);
                              }
                              console.log('File type is = '+ext);
                              }
            }
        }
    
    

    but it fails on the push statement.

    I would eventually have another field with a type of 'Image' or 'other'.

    I presume I then run an if conditions here

     "targets": 1,
                "data": "web_path",
                            "render": function ( data) 
                            {
                //return '<img src=http://toolfolks.com'+data+'" style="height:50px;width:50px;"/>'
                  return '<img src="'+'http://toolfolks.com'+data+'" style="height:50px;width:50px;"/>'
                            }
                },
    

    Along the lines of . if data.type === image ( show image) if not change to link.

    Cheers

    Steve Warby

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    Along the lines of . if data.type === image ( show image) if not change to link.

    It would probably be row.type since data there will be web_path, and you would arguments two and three to the columns.render option, but that's the basic idea.

    I'm not clear on what dataReturned is. If the push is failing, it suggests dataReturned[i] is not an array.

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Hi allan,

    where would I place the code as I am changing the values of the columns.

            columns: [
                { data: "quoteID" , title : "Quote ID" },
                { data: "web_path" , title : "Image 1" },
                {
                           
                           data: "web_path" , title : "Image 1",
                           "render": function (data) {
                            return    '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
    

    It doesn't allow me to add any code within the options

    Cheers

    Steve Warby

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    for ( var i = 0; i < dataReturned.length; i++) {

    Where is this stuff being executed?

    If you want to add additional information that is present in the server, to the data that is sent to the client-side, you'd need to do it in the server-side script.

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Hi Allan,

    been working late 4 am to try and update our existing apps. Decided to finish early but went to bed with Ipad and started reading the blogs and docs. This product is awesome......

    On the client I loop the returned data ( modification of user, users_files, files)

    function quotesReturned() {
         if (req.status == 200) { //success
              //alert('data back '+ req.responseText);
              dataReturned = JSON.parse(req.responseText);
              htmResponse.innerHTML = req.responseText;
              dataReturned['Type'] = [];
    // loop through and add field 'Type' can all be done in one loop.
            dataReturned.forEach(function(e){
            if (typeof e === "object" ){
            e["Type"] = "other";
            
           // console.log('stuff '+e['Type'][i] )
      }
      
    });
    
    //loop through and workout the file type
            dataReturned.forEach(function(e){
            if (typeof e === "object" ){
            var ext = e['web_path'].substr(e['web_path'].lastIndexOf('.') + 1);
            if ( (ext === 'jpeg' ) || ( ext === 'jpg' )|| ( ext === 'png' )|| ( ext === 'gif' ) || ( ext === 'pdf' ))
            
            { e["Type"] = "image"; }
            //console.log(e['web_path']);
           // console.log('stuff '+ JSON.stringify(e))
      }
      
    });
    // create a new array formated as needed
    var currentQuoteID =0;
    var arrayRow = -1 ;
    var fileCount = 0;
    dataReturned.forEach(function(e){
    // now loop through and get the  quoteID and add a new row to a new array ( copying the row data)
    // if the next row = same quoteID push the new web_path to the existing & repeat.
    // if not the same quoteID add a new row. We will end up with one row for each quoteID and x umber of files in each row.
            //console.log(' current quote '+ currentQuoteID + ' = '+ e["quoteID"] + 'file count = '+  fileCount);
            if ( currentQuoteID !== e["quoteID"]) {dataChanged.push(e); arrayRow = arrayRow + 1; fileCount = 1}
          else
            {
                //console.log('just add the filename array Row = ' +arrayRow );
                // need to insert to the array arrayRow
                // dataChanged.push('web_path'+fileCount,e["web_path"]);
                var field = 'web_path'+fileCount;
                var data = webPath+e["web_path"];
                var tempArray = [field,data];
                dataChanged[arrayRow]['web_path'+fileCount] = data
                fileCount = fileCount +1;
            }
            currentQuoteID = e["quoteID"];
           console.log('stuff '+ JSON.stringify(dataChanged));
    });
    

    So What I have is a new array that has the data as

    'quoteID' :'1','web_path' :'xxx.com.image.jpg', 'web_path1' :'xxx.com.image1.jpg, 'web_path2' :'xxx.com.spreadsheet1.xls

    So the columns options I have:

      columns: [
                { data: "quoteID" , title : "Quote ID" },
                { data: "quoteTitle" , title : "Quote Title" },
                //{ data: "web_path" , title : "Image 1" },
                {
                           
                           data: "web_path" , title : "Image 1",
                           "render": function (data) {
                            return    '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
                //{ data: "Type" , title : "Quote ID" },
                
                {data: "notes", title : "Details" },
                 {
                           
                           data: "web_path" , title : "Image 1",
                           "render": function (data) {
                            return    '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
                 {
                           data: "web_path1" , title : "Image 2",
                           "render": function (data) {
                            return   '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
                 {
                           data: "web_path2" , title : "Image 3",
                           "render": function (data) {
                            return   '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
                {
                           data: "web_path3" , title : "Image 4",
                           "render": function (data) {
                            return   '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
               {
                           data: "web_path4" , title : "Image 5",
                           "render": function (data) {
                            return   '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
               {
                           data: "web_path5" , title : "Image 6",
                           "render": function (data) {
                            return   '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
               {
                           data: "web_path6" , title : "Image 7",
                           "render": function (data) {
                            return   '<img src="'+data + '"'+ imageSize + ' "/>' ;
                            }
                           },
                        
                          ]
    

    So I need to accoplish the following

    1. Show images if they exist ( working )
    2. If no image ( eg data:web_path6 is empty ) There won't always be 8 images.
    3. If the file is other ( ie a spread sheet ) show the cell as a link to download the file.

    So I'm not sure where I can put this logic on the client end.

    Can someone do some 'Wizadry' to make it happen..

    Cheers

    Steve Warby

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    2) This should probably be enough:

    if ( ! data ) {
      return '';
    }
    else {
      return '<img ...';
    }
    

    3) Perhaps doing a similar extension check would do:

    if ( data.indexOf('.xlsx') !== -1 ) {
      return '<a ...>Download</a>';
    }
    else {
      return ...
    }
    

    Given that you have the same rendering function 8 times, it would probably be best to set it using columnDefs, so you don't need to repeat it. Keep the columns.data option in the columns though, so each column refers to its own unique data.

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Thanks allan,

    I tried the following ( I struggle knowing where to 'put things' ) so hopefully it's something simple.

    ```
    columns: [

            { data: "quoteID" , title : "Quote ID" },
            { data: "quoteTitle" , title : "Quote Title" },
    
            { data: "web_path",
            if ( data.indexOf('.xlsx') !== -1 ) {             
    
                  return '<a ...>Download</a>';
                  }
                else {
    
                return '<img src="'+data + '"'+ imageSize + ' "/>' ;
                    }
    
            },
    
    
    
    
            {
              ```   
    

    I get

    'Unexpected token '.'. Expected a ')' or a ',' after a parameter declaration'

    on the if statement.

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    You are missing the render parameter. I just showed the inside of what the function would look like - you need to have it inside the render function:

              {
                  data: "web_path",
                  render: function(data, type, row) {
                      if (data.indexOf('.xlsx') !== -1) {
                          return '<a ...>Download</a>';
                      } else {
                          return '<img src="' + data + '"' + imageSize + ' "/>';
                      }
    
                  }
              },
    

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Thanks again,

    got that working

    http://toolfolks.com/surplusAnywhere4/

    I just need to hide the cell if the cell has undefined.

    ie http://toolfolks.com/surplusAnywhere4/undefined

    hide the ugly ' missing image '

    Cheers

    Steve Warby

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Whoops one more.

    I am using the ckeditor to edit one of the columns. So I can have a well formatted product description

    This can become quite long so I need

    To contain the row height and allow the client to scroll the cell.

    When the response expands show th cell full height.

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    I founs this

    table#dtDataChanged tbody td div{
    width:160px;
    max-height:28px;
    overflow:hidden;
    word-wrap:break-word; 
    }
    #dtDataChanged tbody > tr > td { 
    white-space: nowrap; 
    }
    

    but the row still expands

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    table#dtDataChanged tbody td div {
      width:160px;
      max-height:28px;
      overflow: scroll;
    }
    

    is probably what I would use for that.

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Hi Allan,

    the rows are still expanding.

    http://toolfolks.com/surplusAnywhere5/

    Cheers

    Steve Warby

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    I don't see a div with the CSS suggested above:

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Hi Allan,

    running blind here again...

    I have added this to my projects CSS.

    table#dtDataChanged tbody td div {
      width:160px;
      max-height:28px;
      overflow: scroll;
    }
    

    Does this mean dtDataChanged does not have the above.

    Cheers

    Steve Warby

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    It does have that CSS, but there is no div inside the cell for it to be applied to, so it can't be applied. You need a div element for that selector to pick anything up. A renderer could be used to add a div around the content.

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Hi Allan,

    I've played around and can't get it working.

    I presumed ( limited knowledge ) that this would work;

     { data: "quoteTitle" , title : "Title" },
                {data: "notes", 
                title : "Details",
                //className : 'setRowHeight'
                render: function ( data, type, row ) {
                return  "<div class='setRowHeight' "  + data + " </div>";
                }
                },
    

    What is the correct syntax for this?

    Also could I add the max height / scroller options at the same time.

    Cheers

    Steve Warby

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    You need to close the opening div:

    return  "<div class='setRowHeight'>" + data + " </div>";
    

    Allan

This discussion has been closed.