I have a DSP with an entity, containing a picturebutton widget, with the type set to I# (Image from database), on creation of the DSP I load some occurrences of the entity from the database, and the picturebuttons show perfectly, all good so far. 

There is another button in a different (dummy) entity, when I press this, it fires the detail trigger, (scope input,output) which does not populate the picture data in the field on the first entity (although it Does populate at least one other field) during the webload (or reconnect). So when the websave is done, the picture buttons show Error!. No code in the detail trigger affects the entity with the picturebuttons painted, so they should be untouched. 

Is there something I need to set/do to either make the data transfer properly (or better remain in the web browser and not get overwritten by the websave). 



    CommentAdd your comment...

    1 answer


      Hi Iain,

      There are a couple of ways of doing this 

      1) encode the image into a dataurl

      src="data:image/png;base46,{image encoded by $encode's base64}"

      2) Create an image handler - To do this all you have to do is create a small component which takes a key to the image as either a query string or semantic URL, retrieve the image from the database, copy it to $webinfo("output") and set the return HTTP status and mime type. 

      Both should work but the second option has the advantage of lazy loading the images and making the page more responsive - which is not an issue if you are only using a limited number of small images.

      Hope this helps

      1. Iain Sharp

        So, how do you populate the field with these from inside proc? Currently, I just have the picturebutton included in the layout, and uniface populates it (it just doesn't hold the image). 

        And, under what circumstances does the picturebutton as implemented by Uniface, work? Is it supposed to be for USPs only?


      2. Mike Taylor

        Hi Iain

        If you change the field widget to attributesOnly you can set the src attribute in the preSerialize trigger.

        trigger preSerialize
        		raw vPicture
        	vPicture = IMAGE.IMAGES 
        	putitem/id $fieldproperties("IMAGE.IMAGES"), "html:src", $concat("data:image/png;base64,", $encode("BASE64", vPicture))

        When the picture widget is used with a URL or other such reference the picture field is able to reload the image. If the image is persisted in the database then Uniface will create a temporary image file for the web page to load. When the browser has loaded the image this temp file will be cleaned up as Uniface has no idea if it will be needed again and there is no event to say the image is no longer needed. 



      3. Iain Sharp

        Well, that code seems to have the same issue, the data for the picture is not in the $webinfo, and is therefore not loaded into the field on the webload, and the web-save then wipes out the image. The difference is I no longer get an !Error  image. 

        Also, attributes only doesn't respond to the detail trigger, so it's no longer a clickable image. 

        These images are to be maintained by our utterly non technical customers, so I can't rely on them managing files external to the database, I suppose I'll have to write something to dump them back out to something I can then code as a URL. If the contents of the picturebutton are an url, do they persist over a webload?



      4. Mike Taylor

        Is the image stored in the database or assigned in code?

        With my test I have a database entity with an image filed defined as i# r* - the image is stored in the database. I also have a second non-database entity with a button. The button has the code

        trigger detail
        	public web
        	DESC = "Update"

        With this - along with the default pre/postActivate code - the field DESC is updated and the image remains when I click the button (with either a data URL or the picture button).

        The images are not transferred as part of the call-back - the retrieve/reconnect reloads them from the database.



      5. Iain Sharp

        The images are stored in the database, but I'm using a DSP component type sub-entity, so there is no database connection to reload the image from.  They are loaded into the component using a service in another layer and passed via struct parameters and structtocomponent. 

        I'll try using a direct database lookup and see if this 'solves' the issue, but I was presuming (from the component sub-types) that DSPs, like forms, should have no direct database access... 



      6. Iain Sharp

        So, sorry I didn't get back on this, making it the database entity and retrieving the data directly to the DSP component, 'fixes' the issue. 

        Does this mean that we shouldn't use the DSP component subtypes, and treat DSPs as the UI layer (no database access)? Or should it work for those types as well? 

      CommentAdd your comment...