events and forms

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • zaphod42
    New Member
    • Oct 2008
    • 55

    events and forms

    funny thing....I'm dynamically building forms, well, WAS building forms, but for this project I need some very specific validation and logic handling, so while I was changing my functions to deal with this, I ended up with a "form" that is just a span with form elements inside of it, submit works fine (custom submit too), all my validation fires properly, the only thing that isn't working is setting my events.

    When I started I was actually generating a valid html form element, events worked fine when I set them on the fields, however, since I started appending the fields to the span, none of the events I set make it through the creation process..they seem to disappear when I append the form at the end of the function, I had this working once before, and added several things to it, which prolly broke it;)

    really just asking if anyone else has run into a similar problem assigning events to form elements
  • acoder
    Recognized Expert MVP
    • Nov 2006
    • 16032

    #2
    Well, a bit of code would help. Could be quite a number of reasons why it doesn't work.

    Comment

    • zaphod42
      New Member
      • Oct 2008
      • 55

      #3
      I'll see if I can put together a small sample, it's generated from json style notation in a string....it's about 1200 lines of js and a few php files, so I didn't want to try to post the whole thing, I'll see if I can get it on a server with a link....it's a agent tool for a call center, so it's not something that will actually be online.

      Mostly I was just curious if there was a known issue....I use firebug and visual studio for debugging and there isn't an error message in either, I've tried changing the parent node back to form with the same result....Like I said, I'll try to get a version online

      Comment

      • zaphod42
        New Member
        • Oct 2008
        • 55

        #4
        thanks for the thought acoder;) turns out I can't post this particular code online. Apparently large companies don't like proprietary script available for free online:p

        anyway, it turned out that the problem was in my 'bind' method, the known issues of dynamic form generation seem to still be mostly relative to ie and radio boxes;)

        Comment

        • acoder
          Recognized Expert MVP
          • Nov 2006
          • 16032

          #5
          So I gather you've solved the problem? If so, well done. Any chance you could post just the relevant part where you were going wrong?

          Comment

          • zaphod42
            New Member
            • Oct 2008
            • 55

            #6
            yup....this is my tester copy, mostly my stuff with very little relative to the job, so it should be cool to post. There are mosre functions and files that go along with this obviously, but this should give you an idea....the only problem I'm still having is the wierd event when you fire onchange events for a fieldset and it relative radio buttons

            the idea is that we have a set of "template" fields:

            Code:
            GL.FieldItems['EU Email']={
            	label:'EU Email',
            	type:'text',
            	size:15,
            	validator:'required'
            }
            built in a js file (GL.FieldItems) is a reference to these...then we allow them to set up their actual forms using basic html style layout for the test, using "<br>" and the like, but for the forms they type something like

            Code:
            {{field=EU Email, Label=true}}
            I parse the string with:

            Code:
            buildJsonFields=function(o){
            	
            	var testReg=new RegExp(/(.*?)\{\{(.*?)\}\}/g)
            	var form=o.par
            	form.ValiForm={}
            	form.Validate=ValidateForm.bindPart({form:form})
            	o.str.replace(testReg,function($0,$1,$2){
            								 form.appendChild(document.createElement('span')).innerHTML=$1
            								 JsonFieldProps({Jstr:$2,par:form})
            								 return
            								 })
            	return(form)
            }
            which in turn calls another parser style function per "field"

            Code:
            JsonFieldProps=function(o){
            	var form=o.par || tester
            	var Jstr=o.Jstr
            	var Label=false
            	var vis=true
            	var fieldRef=false
            	var formRef=false
            	var button=false
            	//$2 & $3 are, respectively, 'name' = 'value'
            	var tmpstr=Jstr.replace(/((.*?)[=]{1}(.*?)(?:, |,|$))/g,function($0,$1,$2,$3){
            			switch($2){
            				case 'field':
            					fieldRef=$3;
            					break;
            				case 'label':
            					Label=$3;
            					break;
            				case 'visible':
            					vis=$3;
            					break;
            				case 'form':
            					formRef=$3
            					break;
            				case 'button':
            					button=$3
            					}})
            	var field=fieldRef?BuildField({o:fieldRef,form:form}):(formRef?buildJsonForm({str:GL.FormItems[formRef].innerHTML,par:form,name:formRef}):false)
            	if(!formRef){buildLabel({field:field,pos:Label})}
            	if(field){
            		field.style.display=(vis!='false')?'inline':'none'
            		if(field.label){field.label.style.display=(vis!='false')?'inline':'none'}
            	}
            	if(button){
            		switch(button){
            			case 'copy':
            				var buttVal='Copy Form'
            				var buttFunc=form.Validate
            				break;
            			case 'reset':
            				var buttVal='Reset Form'
            				var buttFunc=form.Validate
            				break;
            		}
            		buildButton(butO={atts:{innerHTML:buttVal},func:buttFunc.bind(form.ValiForm)},form)
            	}
            }
            a few functions are called during this, most notably:

            Code:
            BuildField=function(args){
            	var o=(args.o.constructor == String)?GL.FieldItems[args.o]:args.o;
            	if(!o){return}
            	//alert(args.o+', '+EvType)
            	var prop;
            	var style;
            	var method;
            	var inputs={file:'file',checkbox:'checkbox',password:'password',text:'text',radio:'radio'}
            	if(!o.name){o.name=args.form.name+'_'+args.o}
            	if(o.options && inputs[o.type]){var tmpType=o.type;o.type='fieldset';o.style=o.style || {};o.style.position='absolute';o.style.display='inline'}
            	var type=(inputs[o.type])?(document.all?('<input type="'+o.type+'" name="'+o.name+'" />'):'input'):o.type
            	if(((o.type == 'fieldset') || o.ParentNode) && (o.type != 'checkbox')){var EvType='onchange'}
            	else if(o.type=='select'){var EvType='onchange'}
            	else{var EvType='onblur'}
            	var field=document.createElement(type)
            	for(att in o){
            		if(att=='style'){
            			for(style in o.style){
            				field.style[style]=o.style[style]
            			}
            		}else if(att=='checked'){
            			field.setupFunc=function(){setCheckedValue(field.form[o.name], o.value)}
            		}else if((att=='type') && (type!='input')){
            		}else{
            			try{
            			field[att]=o[att]
            		}catch(e){continue}
            		}
            	}
            	field.logic=window[o.logic] || o.logic || false
            	for(i in o.options){
            		var thisArg=args
            		thisArg.o=o.options[i]
            		if(!inputs[tmpType || o.type]){thisArg.o.type='option'}
            		else(thisArg.o.type=tmpType || o.type)
            		thisArg.o.name=o.name
            		thisArg.o.id=o.name+'_'+i
            		thisArg.o.options=false
            		thisArg.o.ParentNode=field
            		BuildField(thisArg)
            	}
            	var parent=o.ParentNode || args.form
            	field.parForm=args.form;
            	parent.appendChild(field);
            	if(o.type==='option'){field.innerHTML=o.label}
            	else{buildLabel({field:field,par:parent})}
            	var width=field.offsetWidth
            	if(tmpType){field.style.position='relative';field.style.width=width+'px';}
            	if(field.validator==='true'){field.validator=GL.Validation[o.type]}
            	field.Validate=ValidateFld.bindPart({field:field})
            	if(o.logic || (o.ParentNode && o.ParentNode.logic)){field[EvType]=field.ParentNode?field.ParentNode.logic.bind(field):window[o.logic]?window[o.logic].bind(field):o.logic}
            	args.form.ValiForm[field.name]=field
            	valiForm=args.form.ValiForm
            	return(field);
            }
            my problem was mostly with my bind function that I use to keep the scopes after a call, that and this whole system has to work on ie6 ::shudder:: There are dozens of better ways to handle this type of thing, but they want what they want;)

            And also, there is no framework driving this other than mine, every function or function call you see are written entirely by me.

            Comment

            • acoder
              Recognized Expert MVP
              • Nov 2006
              • 16032

              #7
              If you mean onchange on a fieldset, some browsers support it, but I don't think it's part of the standards - W3C. Also see this possibly related thread from the newsgroup archives.

              Comment

              • zaphod42
                New Member
                • Oct 2008
                • 55

                #8
                yeah, I figured that out as well, I set the onchange event of the fieldset, but it really works more like a custom method at this point, I have it set up so that on focus of the radios the appropriate argument is sent to the onchange method of the fieldset....I had initially set the radios to onchange also, but ran into a problem as ie fires the events differently than firefox...the onchange event seemed to fire BEFORE the appropriate radio was actually checked, so ie was always a step behind;) but like I said the onfocus event works for the radios;)

                Comment

                Working...