How to access the value of an ImageField in javascript?

Posted by Community Admin on 04-Aug-2018 16:40

How to access the value of an ImageField in javascript?

All Replies

Posted by Community Admin on 16-Nov-2012 00:00

Hi all,

I'm trying to understand how to access Sitefinity data from within a custom widget with a custom backend designer. For starters, I'm building a very simple widget that should just allow the backend user to select an image. I'm using this example, but it seems as if method names have been changed since that post was written:
www.sitefinity.com/.../selecting_sitefinity_4_content_inside_widget_designers

The applyChanges function in the designer javascript file contains this line:

controlData.ImageURL = jQuery(this.get_ImageSelector()).val();

The value is not being passed to my widget...

Can anyone explain how to do this or provide an up to date example? Or an API reference?

Thanks,
Arno

Posted by Community Admin on 16-Nov-2012 00:00

Incomplete, inconsistent and undocumented Client API is something that I've complained long and hard about since v4.0 and unfortunately we seem no closer now than we were back then.

Other than support tickets, your only option is to use a tool such as FireBug and break-point at a useful location in the script - such as 'applyChanges' in a designer.

FWIW, I believe that what you need might be:

controlData.ImageURL = jQuery(this.get_ImageSelector()).get_selectedImageItem().Url;

However, personally I always use this:
controlData.ImageGUID = jQuery(this.get_ImageSelector()).get_selectedImageItem().Id;

I store the GUID rather than the URL, and make the conversion at the server from GUID to MediaURL - which ensures that it's always the current URL - because the URL can change, whereas the GUID remains contstant.  However, this means I need to pass the current URL to the ImageSelector in the designer to initialise it, by referencing a suitable read-only property on the control.

Posted by Community Admin on 16-Nov-2012 00:00

I dont have VS2012 available atm, but just use firefox\firebug and breakpoint that line.

You should be able to use firebug to see method names\properties, etc etc.

I've never been a fan of the "get"\"set syntax and passing down clientIDs from the designers server code....just bloats the code.  Instead I just use jquery to find the item directly with ClientIDMode="Static" so you can just do $("#imagecontrol").val()

Or if you have a control which doesn't support ClientIDMode static then you can find it with a partial ends with selector.  $("[id$='imagecontrol']").val()

Posted by Community Admin on 17-Nov-2012 00:00

Many thanks for your replies MB and Steve. It's weird to distribute an API and not document it. That's a guarantee for lots of questions and frustrated developers. I've reached that point as well. This is taking way too much time...

Anyway, I haven't used Firebug a lot, but I gave it a shot. The function get_selectedImageItem() does not seem to work. I don't see any other obvious method to use either (see attachment). I only see a long list of general methods such as show() and hide().

I know I should work with the GUID eventually. I wanted to started as simple as possible by following the example, but no luck...

Further tips would be great! If I find a solution myself I'll post it here.

Arno

Posted by Community Admin on 17-Nov-2012 00:00

So strange. I'm doing the debugging with Visual Studio 2012 now. The object is loaded (the id is the right one), but I don't see any methods to get Sitefinity data from it. I must be missing something...

Posted by Community Admin on 17-Nov-2012 00:00

I guess I should preface this by saying that I'm sure Telerik would now recommend using Thunder to build a designer, as it's supposed to do all of this plumbing for you.

However... The breakpoint at applyChanges looks correct, but I have to admit that I didn't really read your code properly the first time, and just changed the extension, without noticing the jQuery usage, or thinking about the implication of that.

I you re-read Josh Morales's blog, you'll see that he passes a reference to an ImageField control that is specified on the designer template.

<sitefinity:ImageField ID="ImageSelector" runat="server" DisplayMode="Write" UploadMode="Dialog" DataFieldName="Image" />

He then uses that reference in the designer script, to manipulate the client object - much the same as you would manipulate the client object of a RadControl etc, except that you need to play by the rules of passing references to asp.ajax client components.

He accesses the ImageField control on his Designer Template using a read-only property
protected ImageField ImageSelector
    get return Container.GetControl<ImageField>("ImageSelector", true);

He then passes a reference to the Designer script component, by extending the base ScriptDescriptor in the Designer - which wires up the required reference in the $create() plumbing script used by asp.ajax.
public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
    var descriptors = new List<ScriptDescriptor>(base.GetScriptDescriptors());
    var descriptor = (ScriptControlDescriptor)descriptors.Last();
  
    descriptor.AddComponentProperty("ImageSelector", this.ImageSelector.ClientID);
 
    return descriptors;

And then in the script component he specifies a variable to store this reference
this._ImageSelector = null;

And sets/gets this using a property that matches his ScriptDescriptor specification.
get_ImageSelector: function ()
  
        return this._ImageSelector;
  
    ,
  
set_ImageSelector: function (value)
  
        this._ImageSelector = value;
  
    ,

Assuming that approach, I suspect that my code probably should have been something like
controlData.ImageURL = this.get_ImageSelector().get_selectedImageItem().Url;

I.e. You have a direct reference to the ImageField control's client object, and are using methods of this object - jQuery is not acutally involved in this process.

Hope that helps rather than make matters even more confusing, but as I said at the start, I think that Thunder is now the prefered path for creating designers - although I have to admit I don't use it myself.

Posted by Community Admin on 19-Nov-2012 00:00

Thanks for that thorough explanation MB! I am using Thunder, so the boilerplate code should be alright. It indeed generates the code you have listed, but I'm stuck as soon as I make the customizations I need. My widget has a public property to hold the image URL (later: GUID) as a string. Thunder creates a text box in the designer to configure the URL. That all works fine, but I want an ImageField to select a picture from the libraries rather than filling out a URL. All customizations to make that happen seem fine, until the point that the selected image has to be stored...

I've tried your code without jQuery as well, but no luck. I opened up a support ticket for this, so hopefully this will be solved soon somehow.

Posted by Community Admin on 20-Nov-2012 00:00

Todays technical webinar actually revealed the solution. It was demonstrated that if a widget has a public property of the type GUID, Thunder will offer additional field types for Sitefinity data (including an image selector) when creating a designer for the widget. It will then create the necessary code so that one can see how things are supposed to be done. It was this line specifically I needed in the designer javascript file:

controlData.ImageGUID = this.get_selectedImageGUID().innerHTML

The widget itself needs a public property of type GUID and this code (not created by Thunder):

Protected Overrides Sub InitializeControls(container As GenericContainer)
    Dim MyImage = App.WorkWith.Images.Where(Function(i) i.Id = Me.ImageGUID).Get.FirstOrDefault
 
    Me.Image.ImageUrl = MyImage.MediaUrl
End Sub

Good to know that this is another way to get code samples. We still need the API reference though.

Posted by Community Admin on 20-Nov-2012 00:00

I actually do it by saving the GUID, but configuring the ImageField for type string and initializing it with the MediaUrl from a read-only property on the public control, which fetches the current URL from the saved GUID, along similar lines to your code.

I seem to recall that the reason for this approach was that the ImageField wouldn't display a preview image when initialized with a GUID, but perhaps that's been fixed now.

Nevertheless, the lack of client API documentation, is a major PITA, made even worse by the fact that Telerik keep moving the goal-posts with each minor version - code appears with no explanation as to what it's for or why you might want to use it - let alone documentation on how to use it.

Posted by Community Admin on 23-Nov-2012 00:00

Hello all,

As I understand, the specific problem with the designer which started this thread was solved. Let me know if it's not.

I'll comment on documenting the client APIs. Although I agree that it would be useful, the task cannot be automated and is tedious because of the manual work. The server API reference is built directly from the source code comments inside the Sitefinity assemblies, and we have a tool for the purpose, which makes it manageable. There's no such tool for javascript files that I know. We have to manually write topics for each control and update them manually when the code changes. 

We can do that, but it will consume an enormous amount of time. We decided to invest this time in documenting the most common scenarios according to your feedback and automate the boilerplate stuff that you have to repeat each time in Thunder. Moreover, any javascript code is practically open-source and many frontend developers prefer examining it in Firebug and similar tools, to reading documentation. 

I would be happy to collect a list of client-side controls that we can work on directly from you, but cannot promise a comprehensive list soon. By working on what you mostly use, we make sure that we spend our efforts where needed, rather than producing resources only used by a few.

I hope you understand our thinking here, and I'd be happy to hear other suggestions on how we can improve this.

Regards,
Slavo
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 23-Nov-2012 00:00

@Slavo

So, if I understand your comment:

 - Client API documentation is hard and would take time, so Telerik chooses not do it.

That is a very strange position for a software company to take, but nevertheless...

Examining code with Firebug only gets you so far in this process. It might show you what methods/properties/events/etc are available, but it doesn’t explain what they do, their purpose, and/or why you might want to use them  - or should not use them, as the case might be.

Your argument about needing to change documentation if/when the code changes, works both ways – if a developer uses some undocumented piece of code, there is no guarantee that their own code won’t be broken if/when Telerik make a change... because with no documentation (and therefore no breaking change documentation) the entire process becomes a crap-shoot.

Compounding this is the inconsistent and incomplete state of the client API (perhaps because there is no documentation to enforce it) and the confusing plethora of controls that appear to serve similar functions but have no documentation to explain their application, and why one should be used in preference to another. I don’t know about others, but I am in a constant state of... WTF?

As an example of inconsistency... The PageField publishes events for OnSelectorOpened and OnSelectorClosed, which makes it easy to subscribe to the Open/Close of the selector... however, the ImageField offers no such event, forcing you to subscribe to as many element click events as could possibly open/close the selector, and hope there is nothing you missed. Similarly, the PageField client publishes methods to access the field values, while the ImageField does not – forcing you to access properties that Telerik might change in the future. This means that you need to de-bug each control to find what is and isn't there, as you can't assume consistency, and you can't refer to the documentation - because there isn't any.

However, digressing slightly from the API documentation for a second, my pet hate is the way the Field controls are so difficult to integrate into a designer, because of the way the selector dialog embeds into the dialogBase. The selectors need to be able to run in a separate window and return the selected values (similar to this RadControls example: demos.telerik.com/.../defaultcs.aspx ) but without any documentation it’s difficult to figure out how that can be implemented.

P.S. As an aside, perhaps this might be a starting point for a documentation generator ? - msdn.microsoft.com/.../hh524453.aspx

Posted by Community Admin on 24-Nov-2012 00:00

Hi Slavo,

The problem which started this thread is indeed solves, thanks. I completely understand your point of view: documenting an API is a lot of work (and not a fun task either), and you might question whether that time is better invested elsewhere. However, I also wonder how much time you would save if customers had to ask less questions about this. Better documentation = less questions = less time spend on support I would guess. Part of the questions that would still come could simply be answered with a link to the part of the API reference covering the question.

Also, I have to agree with MB that it's weird for a software provider to provide an API and not document it. Building the backend is a crucial task. I'm not saying every exotic property should have pages of explanations and examples, but I would at least expect a list where one can simple see all methods and properties, on top of a fair number of always up to date examples. I like what Thunder does, although it currently crashes every time right after generating code (I reported that but I'm not sure if anyone is looking into that). Nevertheless, Thunder did generate the code I needed to solve my original problem. But I'm afraid to touch the code once I need something Thunder can't do.

Perhaps using Firebug is not a problem to fulltime Sitefinity developers. I can do a fair bit of programming, but I'm not a fulltime programmer and I don't like javascript at all. That's basically my problem, but I do feel that even someone like me should be able to (easily) create custom widgets with custom designers, that won't break on the next upgrade. And then I suppose there are also fulltime programmers that do not work with Sitefinity all the time. I would think they prefer a bit more docs over Firebug as well. I see Firebug as a debugging tool, not a tool to figure out how a commercial software product works. I tried to use Firebug, but it only helps if you manage to create the right object (through another method). I failed to do so for some reason, so I couldn't even see the specific methods I needed. It took forever to make a little bit of progress.

The link to Microsoft posted by MB looks promising. This forum thread may be interesting as well:
stackoverflow.com/.../generating-javascript-documentation

Posted by Community Admin on 28-Nov-2012 00:00

Hi guys,

I didn't say we'll never do this. My goal was to provide the reasons why we haven't prioritized this before other tasks. As I said, we can start this with a limited number of classes, but cannot promise that we will have an exhaustive list soon.  Please share the most urgent client controls that you need docs for and we can start from there.

All the best,
Slavo
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 28-Nov-2012 00:00

I should think that the Field controls are the obvious candidate for priority, as they are the ones people need to use for designer UI and are always being asked about on these forums.

While you are documenting these, perhaps Telerik might like to look at the features, consistency and suggestions for improvements that have been discussed here since v4.0

Posted by Community Admin on 01-Dec-2012 00:00

Hi Slavo,

I'm new to Sitefinity. At this point, it's hard for me to see which controls are most commonly used. It's just that my first attempt to create a fairly simple custom designer failed, and it was hard to check what I was doing wrong. Another example: I created a designer through Thunder, so that code worked. Just replacing a textbox with a HtmlField caused script errors. Writing worked, reading failed. Also, links to Sitefinity pages within the HtmlField do not change if those pages are moved. I had no idea what's wrong. So I issued a support ticket, it has been reproduced, and I 'm now waiting for a resolution. This should be a simple, basic thing to do in any CMS. It should be spelled out how to do it.

I suppose the Field controls MB is mentioning need to be documented, and I also agree on his statement about consistency. That increases the chance to do things right even with undocumented controls. Basically, any controls that one needs to read/write Sitefinity data in custom designers need to be easy to use as I can't image much websites that would not need them.

Posted by Community Admin on 03-Dec-2012 00:00

Hello all,

Thank you for the information you have shared with as and for all the suggestions. I will make sure that they will be forwarded. Arno, I hope that you will get a solution on the problem you are encountering on the support ticket you have opened. You could then share the conversation with the community.

Kind regards,
Stefani Tacheva
the Telerik team

Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 12-Dec-2012 00:00

Hi,

Yes, the HtmlField works now.

In the designer js file, I needed to replaced this:

$find(this.get_myText().id).get_editControl().set_html(controlData.MyText);


with this:
var htmlText = controlData.MyText ? controlData.MyText : "";
$find(
this.get_myText().id).set_value(htmlText);

to prevent an invalid (non string) value to be set in case controlData.MyText is empty.

Posted by Community Admin on 13-Dec-2012 00:00

Hello,

Thank you for sharing this information with the community.

All the best,
Stefani Tacheva
the Telerik team

Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 21-Jun-2014 00:00

THANK YOU FOR  POSTING THIS SOLUTION.

LACK OF API DOCUMENTATION (CLIENT SIDE AND BACKEND) IS AWFUL. I'M RECOMMENDING MY COMPANY TO NOT EVER USE SITEFINITY AGAIN!!!

Posted by Community Admin on 26-Jun-2014 00:00

Hi,

I wanted to apologize if any negative impressions have been implied by our product and documentation. If there are some specific areas of our documentation which needs to be improved or reviewed, which are missing or incorrect please share their links or some additional information with us. We are always opened to any constructive clients feedback which will makes us understand better where we are currently
and which areas of the Sitefinity product and documentation needs to be sophisticated.

Regards,
Stefani Tacheva
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

This thread is closed