How to access the value of an ImageField in javascript?
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();
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;
controlData.ImageGUID = jQuery(
this
.get_ImageSelector()).get_selectedImageItem().Id;
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()
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
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...
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"
/>
protected
ImageField ImageSelector
get
return
Container.GetControl<ImageField>(
"ImageSelector"
,
true
);
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;
this
._ImageSelector =
null
;
get_ImageSelector:
function
()
return
this
._ImageSelector;
,
set_ImageSelector:
function
(value)
this
._ImageSelector = value;
,
controlData.ImageURL =
this
.get_ImageSelector().get_selectedImageItem().Url;
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.
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
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
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.
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.
@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
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
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,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
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.
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
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);
var
htmlText = controlData.MyText ? controlData.MyText :
""
;
$find(
this
.get_myText().id).set_value(htmlText);
Hello,
Thank you for sharing this information with the community.
All the best,
Stefani Tacheva
the Telerik team
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!!!
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