I am trying to call a java script function when the selected value in a Dojo auto-completer is changed, but I am unable to do so.
Firstly because the standard onchange attribute does not work here, as this is not a standard HTML component.
Secondly I found this documentation ( http://dojotoolkit.org/reference-guide/quickstart/events.html#connecting-to-a-dom-event ) and it is supposed to solve my problem. But somehow I am still not able to connect to a javascript function.
Here is the sample page through which I am trying to test this out.
The JSP:
<s:form id="form">
<sd:autocompleter id="try" list="sampleList"/>
</s:form>
The JS File:
dojo.connect(dojo.byId("try"),"onchange", tryAlert);
function tryAlert(){
alert('successful');
}
I don't know what I have interpreted wrong from the documentation.
Please advise.
Thanks!!
Here is what I ended up doing. For those still stuck in a similar situation, this will be helpful.
In the jsp File do this:
<s:form id="form">
<s:hidden id="chngd"/>
<sd:autocompleter id="try" list="sampleList" valueNotifyTopics="topic"/>
///////////
//Here you can put more autocompleters if you need them , Like I needed them
///////////
</s:form>
In the js file do this:
dojo.event.topic.subscribe("topic", function(){
dojo.byId('chngd').value='try';// I have set the value of the hidden field to desired value here....
//whatever more you want to do....
});
//////////
//Here there would be a subscription (similar to above) for each autocompleter you have put in your jsp.
//////////
So what will happen here is that, whenever an autocompleter is changed it will notify or publish a topic for listeners to listen. Now the subscribe function in java script will listen to its respective 'topic' and when that topic is published, the subscribe will execute the javascript function inside it.
This way whenever an autocompleter is changed a respective javascript function is called, thus we have a -- onchange="javascript function" -- kind of effect.
If you still face trouble, ask for help :).
Ok I guess the struts component for "autocompleter" is dojo's dijit.form.FilteringSelect.
You will find its documentation at http://dojotoolkit.org/api. Once there, open the tree and follow the path dijit/form/FilteringSelect, then deploy the "Event summary" header.
You will find the list of extension points (say events...) the widget accepts. The correct one for you is called "onChange" (mind the capital C).
Also, dojo widgets can be found by id through dijit.byId("yourId") - dojo.byId is for regular dom nodes.
So, for using the onChange extension point, you should do :
<s:form id="form">
<sd:autocompleter id="try" list="sampleList">
<script type="dojo/method" event="onChange" args="newValue">
alert('successful');
</script>
</s:form>
or... if you prefer the javascript way :
dojo.ready(function(){
dijit.byId("try").onChange = function(newValue) {
alert("Changed to new value", newValue);
}
}
Related
I have my own custom non-jQuery ajax which I use for programming web applications. I recently ran into problems with IE9 using TinyMCE, so am trying to switch to CKeditor
The editable text is being wrapped in a div, like so:
<div id='content'>
<div id='editable' contenteditable='true'>
page of inline text filled with ajax when links throughout the site are clicked
</div>
</div>
When I try to getData on the editable content using the examples in the documentation, I get an error.
I do this:
CKEDITOR.instances.editable.getData();
And get this:
Uncaught TypeError: Cannot call method 'getData' of undefined
So I figure that it doesn't know where the editor is in the dom... I've tried working through all editors to get the editor name, but that doesn't work-- no name appears to be found.
I've tried this:
for(var i in CKEDITOR.instances) {
alert(CKEDITOR.instances[i].name);
}
The alert is just blank-- so there's no name associated with it apparently.
I should also mention, that despite my best efforts, I cannot seem to get the editable text to have a menu appear above it like it does in the Massive Inline Editing Example
Thanks for any assistance you can bring.
Jason Silver
UPDATE:
I'm showing off my lack of knowledge here, but I had never come across "contenteditable='true'" before, so thought that because I was able to type inline, therefore the editor was instantiated somehow... but now I'm wondering if the editor is even being applied to my div.
UPDATE 2:
When the page is loaded and the script is initially called, the div does not exist. The editable div is sent into the DOM using AJAX. #Zee left a comment below that made me wonder if there is some other command that should be called in order to apply the editor to that div, so I created a button in the page with the following onclick as a way to test this approach: (adapted from the ajax example)
var editor,html='';config = {};editor=CKEDITOR.appendTo('editable',config, html );
That gives the following error in Chrome:
> Uncaught TypeError: Cannot call method 'equals' of undefined
> + CKEDITOR.tools.extend.getEditor ckeditor.js:101
> b ckeditor.js:252
> CKEDITOR.appendTo ckeditor.js:257
> onclick www.pediatricjunction.com:410
Am I headed in the right direction? Is there another way to programmatically tell CKEditor to apply the editor to a div?
UPDATE 3:
Thanks to #Reinmar I had something new to try. The most obvious way for me to test to see if this was the solution was to put a button above the content editable div that called CKEDITOR.inlineAll() and inline('editable') respectively:
<input type='button' onclick=\"CKEDITOR.inlineAll();\" value='InlineAll'/>
<input type='button' onclick=\"CKEDITOR.inline('editable');\" value='Inline'/>
<input type='button' onclick=\"var editor = CKEDITOR.inline( document.getElementById( 'editable' ) );\" value='getElementById'/>
This returned the same type of error in Chrome for all three buttons, namely:
Uncaught TypeError: Cannot call method 'equals' of undefined ckeditor.js:101
+ CKEDITOR.tools.extend.getEditor ckeditor.js:101
CKEDITOR.inline ckeditor.js:249
CKEDITOR.inlineAll ckeditor.js:250
onclick
UPDATE 4:
Upon further fiddling, I've tracked down the problem being related to json2007.js, which is a script I use which works with Real Simple History (RSH.js). These scripts have the purpose of tracking ajax history, so as I move forward and back through the browser, the AJAX page views is not lost.
Here's the fiddle page: http://jsfiddle.net/jasonsilver/3CqPv/2/
When you want to initialize inline editor there are two ways:
If element which is editable (has contenteditable attribute) exists when page is loaded CKEditor will automatically initialize an instance for it. Its name will be taken from that element's id or it will be editor<number>. You can find editors initialized automatically on this sample.
If this element is created dynamically, then you need to initialize editor on your own.
E.g. after appending <div id="editor" contenteditable="true">X</div> to the document you should call:
CKEDITOR.inline( 'editor' )
or
CKEDITOR.inlineAll()
See docs and docs.
You can find editor initialized this way on this sample.
The appendTo method has different use. You can initialize themed (not inline) editor inside specified element. This method also accepts data of editor (as 3rd arg), when all other methods (CKEDITOR.inline, CKEDITOR.replace, CKEDITOR.inlineAll) take data from the element they are replacing/using.
Update
I checked that libraries you use together with CKEditor are poorly written and cause errors you mentioned. Remove json2007.js and rsh.js and CKEditor works fine.
OK, so I have tracked down the problem.
The library I was using for tracking Ajax history and remembering commands for the back button, called Real Simple History, was using a script called json2007 which was intrusive and extended native prototypes to the point where things broke.
RSH.js is kind of old, and I wasn't using it to it's full potential anyway, so my final solution was to rewrite the essential code I needed for that, namely, a listener that watched for anchor (hash) changes in the URL, then parsed those changes and resubmitted the ajax command.
var current_hash = window.location.hash;
function check_hash() {
if ( window.location.hash != current_hash ) {
current_hash = window.location.hash;
refreshAjax();
}
}
hashCheck = setInterval( "check_hash()", 50 );
'refreshAjax()' was an existing function anyway, so this is actually a more elegant solution than I was using with Real Simple History.
After stripping out the json2007.js script, everything else just worked, and CKEditor is beautiful.
Thanks so much for your help, #Reinmar... I appreciate your patience and effort.
Maybe I've picked a totally inappropriate/bad example.
What I have is a user control that contains a bunch of dynamically created Telerik RadGrids.
My user control is added to a couple of Telerik RadPageViews that are part of a RadMultiPage that is used alongside a RadTabStrip.
What I need to do is call a Javascript function in my usercontrol to update it's display whenever it's parent RadPageView is selected.
So basically I have the following Javascript code:
function OnClientTabSelected(sender, args)
{
// Get the MyControl that is on this tab
var myControl = $find("whatever");
// Call a method that updates the display
myControl.doSomething();
}
Thanks,
David
You can add a wrapper div in your User Control and then extend that div using jQuery to add your desired methods and properties. The trick is to set the div's id='<%=this.ID%>' - that way the div has the same ID as the User Control (which is fine because the User Control doesn't actually render anything - only its contents).
Then back on your containing page, you can just reference your UserControl's ID using $get('whatever') - and you'll actually select your extended div.. which will have all your methods and properties on it.
The nice thing about this approach is that all of your methods and properties and neatly scoped and nothing is in the global namespace.
I have a full demo solution and details here if you want more info:
http://programmerramblings.blogspot.com/2011/07/clientside-api-for-aspnet-user-controls.html
Just make a call to javascript method in input button if you are sure about the name of that function.
<input type="button" value="test" onclick="doSomething()" />
If you place any javascript code in the control that will be spit on the page and it will be available for calling provided both of them are in the same form.
for example your code will look like this if you look into the source of that page.
<script type="text/javascript">
function doSomething()
{
alert(new Date());
}
</script>
<div>
<span id="MyControl1_Label1">Dummy label</span>
</div>
<hr />
<input type="button" value="test" onclick="doSomething()" />
Edit: This is not a good way to access these methods in my opinion. When you are putting some javascript code inside a control then it should be used in that control only (There is no rule as such, its just a design suggestion). If you are trying to access javascript code of a control from outside that control then you need to revisit your design.
If you can give us more details on why you want to access that method, may be we can suggest some better way to do that.
Update: (As you have modified your question): Bit tricky to answer this as I dont have hands on experience with Rad controls. I guess there should be some feature which will help you to update the controls in that page without using javascript, may be have a look at clientside-API provided for Rad.
May be somebody who knows about RAD controls will help you.
You should make the control method public
public void doSomething
and call this from the page
myControl1.doSomething();
Working with Web2Py. I'm trying to attach some javascript either to a field (onchange) or to the form (onsubmit), but I see absolutely no way to pass such argument to crud.create or to form.custom.widget.
Anyone has an idea?
Of course there is a way. The appropriate way is to ask people on the web2py mailing list who know how to, as opposed to generic stack overflow users who will guess an incorrect answer. :-)
Anyway, assume you have:
db.define_table('image',
Field('name'),
Field('file', 'upload'))
You can do
def upload_image():
form=crud.create(db.image)
form.element(name='file')['_onchange']='... your js here ...'
form.element('form')['_onsubmit']='... your js here ...'
return dict(form=form)
Element takes the css3/jQuery syntax (but it is evaluated in python).
I do not believe there is a way to do this directly. One option is just to manipulate web2py generated HTML, it is just a string. Even cleaner, in my opinion, is just to bind the event using jQuery's $(document).ready() function.
Say you have a database table (all is stolen from web2py's docs):
db.define_table('image',
Field('name'),
Field('file', 'upload'))
With form:
def upload_image():
return dict(form=crud.create(db.image))
Embedded in a view (in the simplest manner):
{{=form}}
And you want to add an onblur handler to the name input field (added to the view):
<script type="text/javascript">
$(document).ready(function(){
$("#image_name").blur(function(){
// do something with image name loses focus...
});
});
</script>
When I click on the hx:commandExButton the Javascript function should get called, but it is not getting called. The Javascript function is as follows:
function test() {
alert('ss');
return "true";
}
The hx:commandButton is as follows:
<hx:commandExButton
type="submit"
value="Search"
styleClass="action2" id="searchButton"
onclick="return test();"
action="#{pc_WorkInProgressUserGrid.doSearchButtonAction}"
immediate="true">
</hx:commandExButton>
Any suggestion would be helpful.
First step would be to check the generated HTML output to verify if it looks right. It may for instance happen that the hx:commandExButton itself didn't take the onclick attribute value correctly into account. As a test, you could try to get rid of it and use the standard JSF h:commandButton instead.
Further I also recall something about a crazy <hx:scriptCollector> tag which you are supposed to wrap the piece of JSF code with whenever you'd like to use Javascript in combination with IBM Faces Client components.
E.g.
<hx:scriptCollector id="someid">
<hx:form>
<hx:commandExButton />
</hx:form>
</hx:scriptCollector>
I don't know JSF, but it's immediately obvious that you have omitted a " after true, and also a >
Are those ** supposed to be there? And writing method before a function is definitely not part of standard JavaScript.
I have a Select dropdown on the form of an ActiveScaffold. I am trying to hide some of the fields on the form if a particular value is selected.
A [similar question][1] was posted to the ActiveScaffold Google Group, and the supplied Prototype code looks to do what I need, however I don't know where I need to add this.
--
I tried taking a copy of -horizontal-subform-header.html.erb from Vendor/plugins/
active_scaffold/frontends/default/views, placing it in views folder of my controller, and then adding my script into it:
<script type="text/javascript">
document.observe('dom:loaded', function() { //do it once everything's loaded
//grab all the product-input classes and call 'observe' on them :
$$('.product-input').invoke('observe', 'change', function(e) {
this.up('td').next('td').down('input').hide();
});
});
</script>
... but that doesn't seem to work properly. It works if I use a URL to go direct to the form (i.e. http://localhost:3000/sales/20/edit?_method=get). But when I test it with the main list view (i.e. http://localhost:3000/sales/) and opening the form via Ajax, then it doesn't work. Looking at the HTML source the just does not appear.
The common place for adding JavaScript is application.js found in public/javascripts. I'm a jQuery guy myself, however I'm sure you can hook up to the onchange event in application.js with prototype. A quick search looks like Event.observe should do the trick.