PDA

View Full Version : Basic Dialog Form plus submit example?



rob30UK
12 Jan 2007, 9:09 AM
I have looked all over, but cant seem to find what I want and assume there isnt an existing example.

I want a simple dialog that gathers email address and website address....

Can anyone point me in the right direction? I pretty new to YUI and Jacks excellent yui-ext work.

Your helps would be most welcomed.

Thanks,

Rob

Animal
12 Jan 2007, 11:04 AM
This is what we doctors call "work".

rob30UK
12 Jan 2007, 1:11 PM
I'm sure you do....

However, I am working pretty hard to get my head round this. What I'm doing I am sure is a very common task thats been done loads in yui-ext. I'm sure an example, or tutorial exists, or maybe someone out there is willing to share some EXISTING code I can get an idea from. I just want a nudge in the right direction.

I didnt ask you to do it for me did I?

I am a new member here.... this is my second post, and with respect (as an owner of a large forum myself), I dont think your reply was in any way helpful or constructive.

tryanDLS
12 Jan 2007, 1:21 PM
As the owner of large forum, you should be familar with the numerous posters who want something for nothing. Your post doesn't indicate that you tried and ran into a problem, which somebody might have a solution for.

Did you try to put a form in the simple dialog sample? Did you look at the samples at all? You could probably drop the dialog from the blog sample into your app with little effort.

rob30UK
12 Jan 2007, 2:33 PM
As the owner of large forum, you should be familar with the numerous posters who want something for nothing. Yes, We get that a fair bit being a design / development forum... and the help is usually given in cases where people have tried. We get a lot of 'do my homework' posts which frankly upset me in much the same way as they probabally upset you.
Your post doesn't indicate that you tried and ran into a problem, which somebody might have a solution for. - Well, that is true, yes - I apologise.... fact is, I've been banging my head on the wall with it for hours. I can get the form in the dialog, of course, but how to submit it with ajax and then close the form - I've been looking for something that can validate input also.

I am a server side developer (mainly ASP and a tiny bit of PHP) and AJAX (the javascript bit) is kind of hard to bend my brain around as ASP isnt really an OOP language.


Did you try to put a form in the simple dialog sample? Did you look at the samples at all? Yes I did look at the samples.... but was looking for one with a form (any form) that submits via AJAX, and then closes.
You could probably drop the dialog from the blog sample into your app with little effort. Thats sounds as though it would have everything in it I would need to learn from....... I just cant find it... it's not in the documentation under examples as far as I can tell... maybe I'm blind. Do you have a url?

tryanDLS
12 Jan 2007, 3:09 PM
It's not in the doc center, but it is in the examples folder of the download pkg in examples\dialog\blog.html. The tabs examples I believe also illustrate using UpdateManager to load tab content via Ajax.

brian.moeskau
12 Jan 2007, 3:18 PM
Hi Rob,

The problem for us is that there are lots of ways to accomplish things and the question was pretty open-ended. Also, it's hard to summarize what you're asking in a breif answer as there are lots of pieces of code required for a good example. Most people are busy actually building their apps, not putting together tutorials (hopefully this will change, but realize that the framework is still only a few months old and we're mostly pretty new too!).

That said, I'll try to point you in the right direction.

I have a page with a form in a dialog like so (all html/code abbreviated obviously):


<form action="[server page]" name="myform" method="post" id="myform" onsubmit="return false;">
<div id="my-dlg" style="visibility:hidden;">
<div class="ydlg-hd" id="title">Dialog Title</div>
<div class="ydlg-bd">
<div id="main-tab" class="ydlg-tab" title="Details">
<div class="inner-tab">
<input type="hidden" id="evt-id" name="id" />
<label for="title">Title:</label> <input type="text" id="evt-title" name="title" />

<label for="startdate">Start:</label> <input type="text" id="evt-startdate" name="startdate" />

<label for="enddate">End:</label> <input type="text" id="evt-enddate" name="enddate" />

<label for="url">Url:</label> <input type="text" id="evt-url" name="url" />
</div>
</div>
<div id="info-tab" class="ydlg-tab" title="Additional Info">
<div class="inner-tab">
[more form elements or whatever]
</div>
</div>
</div>
<div class="ydlg-ft">
<div id="dlg-msg">
<span id="post-error" class="posting-msg">../../images/warning.gif<span id="post-error-msg"></span></span>
<span id="post-wait" class="posting-msg">../../images/grid/loading.gifSaving event...</span>
</div>
</div>
</div>
Standard form wrapped in a tab div, wrapped in a dialog structure. Note the onsubmit="return false;" so the form doesn't post the page back. Make sure that the form wraps your dialog and is not embedded inside it -- otherwise it will not submit correctly. You'll need js code that actually sets up the dialog -- see the docs for that. The trick to getting a button is adding it programmatically to the dialog:


okButton = evtDialog.addButton('Save', this.saveForm, this);
Then you simply code the "saveForm" routine that does all the work. Again, there are many ways of doing this depending on what platform etc. Here's an example of just using the YUI way of doing it:


saveForm : function(e) {
okButton.disable();
YAHOO.util.Connect.setForm(document.getElementById('myForm'));

var successCB = function(o){
try {
okButton.enable();
var data = renderer.parse(o.responseText);
if (data) {
if (data.status == "ok") {
renderer.replace(data.event);
dialog.hide();
this.showMsg('Event "' + data.event.title + '" was updated');
}
else {
// show dialog errors
alert(data.msg);
}
}
else {
alert(o.responseText);
}
}
catch(er) {
alert(er);
}
};

var failureCB = function(o){
okButton.enable();
alert(o.responseText);
};

YAHOO.util.Connect.asyncRequest('POST', '[server page]',
{ success: successCB, failure: failureCB, scope: this });
},
There's lots of stuff in here that I don't have time to explain, like how to implement a custom renderer, etc. but it shows submitting the form, getting the callback, and hiding the dialog only on success (dialog.hide()). This should point you in the right direction, but please take the time to go through the example projects, esp. the feed viewer. That's what most of us have done to learn it and get examples!

HTH, Brian

brian.moeskau
12 Jan 2007, 3:23 PM
Re: validating input, that is not there yet except for the validators built into the grid class. However, the next major version of Ext AFTER .40 will most likely contain a comprehensive forms architecture including generic form validation. For now, however, you'll have to roll your own.

rob30UK
12 Jan 2007, 3:38 PM
bmoeskau, I cant thank you enough...

Between your code, and the example you kindly pointed me too (which was under my nose... rofl) I'l easy have enough to take it from here.

I will be making a donation to the project once this app is built.

brian.moeskau
12 Jan 2007, 3:47 PM
Hey Rob,

Glad it helped. If you have any specific issues getting things working, please don't hesitate to post your code! The folks here are usually pretty quick to spot issues and suggest solutions when there's something to look at.

Brian

rob30UK
13 Jan 2007, 4:50 AM
Hi...

Regarding you example above...

I've got it all working... minus the submitting part.

Does the php page need to return anything specific to let the function know it was successful?

I always get an 'object error' in an alert box. I figure maybe the php needs to return something specific, does it?

btw: here is the code I'm using

var newsLetter = function(){
// everything in this space is private and only accessible in

the newsLetter block

// define some private variables
var dialog, showBtn;

var toggleTheme = function(){
getEl(document.body, true).toggleClass('ytheme-gray');
};
// return a public interface
return {
init : function(){
showBtn = getEl('subscribe');
// attach to click event
showBtn.on('click', this.showDialog, this, true);
getEl('theme-btn').on('click', toggleTheme);
},

showDialog : function(){
if(!dialog){ // lazy initialize the dialog and only

create it once
dialog = new YAHOO.ext.BasicDialog("my-dlg", {
modal:true,
autoTabs:true,
draggable:true,
width:500,
height:200,
shadow:true,
minWidth:300,
minHeight:250,
proxyDrag: true
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);
okButton = dialog.addButton('Subscribe',

this.saveForm, this);
}
dialog.show(showBtn.dom);
},

saveForm : function(e) {
alert('submit pressed');
okButton.disable();
YAHOO.util.Connect.setForm(document.getElementById

('myForm'));

var successCB = function(o){
try {
okButton.enable();
var data = renderer.parse(o.responseText);
if (data) {
if (data.status == "ok") {
renderer.replace(data.event);
dialog.hide();
this.showMsg('Event "' + data.event.title + '"

was updated');
}
else {
// show dialog errors
alert(data.msg);
}
}
else {
alert(o.responseText);
}
}
catch(er) {
alert(er);
}
};

var failureCB = function(o){
okButton.enable();
alert(o.responseText);
};

YAHOO.util.Connect.asyncRequest('POST',

'http://my.domain.com/test/testajax.php',
{ success: successCB, failure: failureCB, scope: this

});
//URL above is changed for privacy purposes
}
};
}();

// using onDocumentReady instead of window.onload initializes the

application
// when the DOM is ready, without waiting for images and other

resources to load
YAHOO.ext.EventManager.onDocumentReady(newsLetter.init, newsLetter,

true);

Animal
13 Jan 2007, 5:10 AM
You should run this in Firefox with the Firebug addon.

Set a breakpoint at the first line of successCB then step through.

What is the variable "renderer"?

rob30UK
13 Jan 2007, 5:22 AM
This is weird....

I set a breakpoint on this line inside the successCB function:
okButton.enable();

The debugger never kicked in... I can therefore assume the callback processes isnt kicking in?

Not sure why though...

Ideas?

rob30UK
13 Jan 2007, 5:29 AM
if i set the debugger to break on all errors, then when i click submit, it stops inside utlities.js with two errors. line 188, which is this:
var oElement,oName,oValue,oDisabled;var hasSubmit=false;for(var i=0;i<oForm.elements.length;i++){oElement=oForm.elements[i]; oDisabled=oForm.elements[i].disabled;oName=oForm.elements[i].name; oValue=oForm.elements[i].value;if(!oDisabled&&oName)

and line 85
var wrappedFn=function(e){return fn.call(scope,YAHOO.util.Event.getEvent(e),obj);} ;var li=[el,sType,fn,wrappedFn,scope];var index=listeners.length;listeners[index]=li; if(this.useLegacyEvent(el,sType)){var legacyIndex=this.getLegacyIndex(el,sType); if(legacyIndex==-1||el!=legacyEvents[legacyIndex][0]){legacyIndex=legacyEvents.length; legacyMap[el.id+sType]=legacyIndex;legacyEvents[legacyIndex]=[el,sType,el["on"+sType]]; legacyHandlers[legacyIndex]=[];el["on"+sType]=function(e){ YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(e),legacyIndex);};}

Animal
13 Jan 2007, 5:32 AM
Sometimes the Firebug debugger doesn't sort of "register" the breakpoint until you refresh the page. It's a bit annoying. I've noticed that I sometimes set breakpoints, and they don't trigger first time.

What happens when you set a breakpoint in the failure function too?

rob30UK
13 Jan 2007, 5:34 AM
will try that now....

rob30UK
13 Jan 2007, 5:36 AM
weird.....

It never enters that function either.

Animal
13 Jan 2007, 5:45 AM
OK, two things.

1 Use connect-debug.js from the YUI library rather then connect.js. That way, you'll see any exceptions in the Connect calls being logged to the Firebug console.

2. Go to Firebug's "Net" tab, and see if the XMLHttpRequest is actually being sent, and see what the response looks like.

rob30UK
13 Jan 2007, 5:54 AM
maybe I'm stupid, but i cant see a 'net' tab.

rob30UK
13 Jan 2007, 5:57 AM
ok... using the connection debug stuff, when i load the page, the console is totally blank (so far so good)....

The second I sit submit, I get this in the console:-



oForm has no properties -> connection-debug.... (line 662)
anonymous -> connection-debug.... (line 662)
anonymous- -> test.htm# (line 214)
anonymous -> yui-ext.js (line 841)
anonymous -> yui-ext.js (line 230)
anonymous -> utilities.js (line 85)

Animal
13 Jan 2007, 6:00 AM
Pop up firebug from the little green circular icon at the right end of the status bar.

At the top of it's region it has "Inspect Clear Profile"

On the next line it has which tab view you are in "Console HTML CSS Script DOM Net".

When you were debugging, you'll have been in the "Script" tab. The "Net" one is to the right.

rob30UK
13 Jan 2007, 6:01 AM
Ok....

Typical me, coming from a case insensitive ASP background....

it was a case issue when setting up the form...

Its now working, yet when i click submit, I now have an error:

ReferenceError : renderer is not defined.

Animal
13 Jan 2007, 6:10 AM
Yeah, I was wondering what that was. You copied and pasted the code. It's up to you what to do with the responseText.

Unless you do an UpdateManager.formUpdate() which submits the form, and updates the UpdateManager's Element with the results.

rob30UK
13 Jan 2007, 7:18 AM
hi.

Sorry to bug you guys again, but the submit (subscribe) button, does absolutely nothing in interenet explorer...

Here is the code:
<script tyle="text/javascript">



var newsLetter = function(){
// everything in this space is private and only accessible in the newsLetter block

// define some private variables
var dialog, showBtn;

// return a public interface
return {
init : function(){
showBtn = getEl('subscribe');
// attach to click event
showBtn.on('click', this.showDialog, this, true);
},

showDialog : function(){
if(!dialog){ // lazy initialize the dialog and only create it once
dialog = new YAHOO.ext.BasicDialog("my-dlg", {
modal:true,
autoTabs:true,
draggable:true,
width:500,
height:200,
shadow:true,
minWidth:300,
minHeight:250,
proxyDrag: true
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);
okButton = dialog.addButton('Subscribe', this.saveForm, this);
}
dialog.show(showBtn.dom);
},

saveForm : function(e) {
myform = document.getElementById('myform');
evtname = document.getElementById('evt-name').value;
evtemail = document.getElementById('evt-email').value;
var bad = 1;
if (evtname == "") {
alert("Your name is a required field.");
bad = 1;
return false;
} else {
bad = 0;
}
if (evtemail == "" && bad == 0) {
alert("Your email address is a required field.");
bad = 1;
return false;
} else {
bad = 0;
}
if (bad == 0) {
okButton.disable();
YAHOO.util.Connect.setForm(myform);
okButton.enable();
var successCB = function(o){
try {
var data = o.responseText;
if (data=='ok') {
alert ("Your subscription was added! Thank you " + evtname);
dialog.hide();
}
else {
alert(o.responseText);
}
}
catch(er) {
alert(er);
}
};

var failureCB = function(o){
okButton.enable();
alert(o.responseText);
};

YAHOO.util.Connect.asyncRequest('POST', 'http://my.domain.com/test/testajax.php',
{ success: successCB, failure: failureCB, scope: this });
}
}
};
}();

// using onDocumentReady instead of window.onload initializes the application
// when the DOM is ready, without waiting for images and other resources to load
YAHOO.ext.EventManager.onDocumentReady(newsLetter.init, newsLetter, true);
</script>

This has me stumped, because it works in opera and firefox.

Any ideas?

rob30UK
13 Jan 2007, 7:32 AM
I just learned that you HAVE TO use var = blah in IE to assign new variables...

This is done and dusted now. you may close this thread if you wish!

Thanks for your help everyone!

brian.moeskau
13 Jan 2007, 9:03 AM
Just a note on the "renderer" var from my original snippet -- as I mentioned originally, that was referring to a custom renderer function implemented very similarly to how Jack did the Feed Viewer example. He passes the response text to a custom class that evals the json into an object and populates a view with the data. As Animal mentioned, it's your job to fill in the blanks with what to actually do with the response in your own app (as you've done). The renderer-type approach might be something to look into once you start returning non-trivial data that requires logic behind it's display. Just FYI for anyone else reading this. Glad you got it working :)

brian.moeskau
13 Jan 2007, 9:11 AM
Rob, one other note. I noticed that you're getting fields like this:


evtname = document.getElementById('evt-name').value;

That's perfectly valid of course, but you will probably want to get in the habit of doing:


evtname = getEl('evt-name');
if (evtname.dom.value == "") { ...

You'll normally want some of the functionality of Ext.Element in a non-trivial app, plus that shorthand is usually less typing anyway. You may already be aware of the Element object and skipped it for this simple example, but I just wanted to make sure. getEl also keeps in internal cache of every element you access, making it very quick even when using it multiple times to retrieve the same element.