Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Customising the CMS /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

custom form madness in the CMS


Go to End


4 Posts   2722 Views

Avatar
craesh

Community Member, 25 Posts

22 June 2010 at 4:04am

Hi!

I'm following the tutorial creating-a-module to create exactly that - an own module for the backend. But I'm stuck... there isn't enough documentation and there is something happening during the execution of javascript I can't understand.

Btw, I'm still on SS 2.3.

What I want to do: I want to have a button on the left panel, after clicking that a form should appear in the main panel. Later I want to upload a file with this form and process the file... but anyway, that's still to come. I even don't get my form!

What I've done: Followed the creating-a-module tutorial. I've added a new button to the left panel, based on the 'addlink' button, and changed the url to point to my method in the controller script (that thing derived from LeftAndMain).

So in my template for the left panel:

<ul id="TreeActions">
		<li class="action" id="uploadXmlFile"><button><% _t('UPLOADFILE','Upload File') %></button></li>
		<li class="action" id="addlink"><button><% _t('CREATENL','Create New Link xXx') %></button></li>
		<li class="action" id="deletelink"><button><% _t('DEL','Delete Link xXx') %></button></li>
	</ul>
	<div style="clear:both;"></div>
	<form class="actionparams" id="uploadXmlFile_options" style="display: none" action="admin/disease_search/showUploadXmlFileDialog">
		<input type="submit" value="<% _t('UPLOADFILE','Upload') %>" />
	</form>
	<form class="actionparams" id="addlink_options" style="display: none" action="admin/disease_search/addlink">
<!-- etc... nothing modified from here on -->

My JS file looks like:

_HANDLER_FORMS['uploadXmlFile'] = 'uploadXmlFile_options';

XmlFileUploadForm = Class.extend('CMSRightForm');
XmlFileUploadForm.prototype = {
	intialize: function() {
		this.CMSRightForm.initialize();
	},
	
	loadPage_url : 'admin/disease_search/getXmlFileUploadForm',
	
	/**
	 * Load the given URL (with &ajax=1) into this form
	 */
	loadURLFromServer : function(url) {		
		if ( !url.match( /^https?:\/\/.*/ ) )
			url = document.getElementsByTagName('base')[0].href + url;
		
		new Ajax.Request( url + '?ajax=1', {
			asynchronous : true,
			onSuccess : function( response ) {
				$('Form_XmlFileUploadForm').successfullyReceivedPage(response);
			},
			onFailure : function(response) { 
				alert(response.responseText);
				errorMessage('error loading page',response);
			}
		});
	},
	
	successfullyReceivedPage : function( response ) {			
		// must wait until the javascript has finished
		document.body.style.cursor = 'wait';
	
		this.loadNewPage( response.responseText );
		
		var subform;
		if ( subform = $('Form_MemberForm') ) subform.close();
		if ( subform = $('Form_SubForm') ) subform.close();
		
		// must wait until the javascript has finished
		document.body.style.cursor = 'default';
		
	},
	didntReceivePage : function(response) {
		errorMessage('error loading page', response); 
	},
			
	
	/**
	 * Request a page from the server via Ajax
	 */
	getPageFromServer : function() {
		if ( this.loadPage_url ) {
			url = this.loadPage_url;
			statusMessage("loading...");
			this.loadURLFromServer(url);
		}
	}
}

XmlFileUploadForm.applyTo('#Form_XmlFileUploadForm', 'right');


uploadXmlFile = {
	button_onclick : function() {
		uploadXmlFile.showNewForm();
		return false;
	},
 
	showNewForm : function() {
		Ajax.SubmitForm('uploadXmlFile_options', null, {
			onSuccess : function(response) {
				Ajax.Evaluator(response);
			},
			onFailure : function(response) {
				errorMessage('Error', response);
			}
		});
	}
}

Behaviour.addLoader(function () {
	/* like in the tutorial */
	
	Observable.applyTo($('uploadXmlFile_options'));
	$('uploadXmlFile').onclick = uploadXmlFile.button_onclick;
	$('uploadXmlFile').getElementsByTagName('button')[0].onclick = function() {return false;};
});

And I have a new Form named "Form_XmlFileUploadForm" in my right panel

<% if EditForm %>
	$EditForm
<% else %>
		<form id="Form_EditForm" action="admin/disease_search/?executeForm=EditForm" method="post" enctype="multipart/form-data" style="$LogoStyle">
			<% _t('WELCOME1','<p>Welcome to the Random Links -- xXx') %>
			<% _t('WELCOME2','admin section.  Please choose a link from the left. --xXx </p>') %>
		</form>
<% end_if %>

<% if XmlFileUploadForm %>
	$XmlFileUploadForm
<% else %>
	<form id="Form_XmlFileUploadForm" action="admin/disease_search/getXmlFileUploadForm" method="post" enctype="multipart/form-data" style="$LogoStyle">
	</form>
<% end_if %>

The methods I call are

	public function showUploadXmlFileDialog() {
		FormResponse::add("$('Form_XmlFileUploadForm').getPageFromServer();");
		return FormResponse::respond();
	}
	
	public function getXmlFileUploadForm() {
		$validator = null;//new RequiredFields( 'File' );
		
		$fields = new FieldSet(
			new FileField( 'File', 'Upload File' )
		);
 
	    $actions = new FieldSet(
			new FormAction( 'doUploadXmlFile', 'Upload File' )
		);
 
		$form = new Form( $this, "XmlFileUploadForm", $fields, $actions, $validator );
		return $form;
	}
	
	function doUploadXmlFile( $data = null, $form = null ) {	  	
	  	return FormResponse::respond();		
	}

Ok, what I hope you got an overview of my code. There shouldn't be anything missing, except for the parts I copied from the tutorial but didn't touch since then. But I can give you the whole files through pastie if you want.

What's happening? I see my filefield as soon as I hit the tab for my module in my CMS. I don't know why SS knows "XmlFileUploadForm" will contain a filefield and the submit button, but anyway... thats not my problem. If I click my button in the left pane, "showUploadXmlFileDialog" gets called, returns that ajax response that calls "getXmlFileUploadForm". But all I get in response is not the form I expect (the form I already see...), but simply "Behaviour.addLoader(hideLoading);" - nothing else. This text gets pasted into my form, the filefield and the submit button disapear and all I can see is this text in plain text in in my CMS. It should get executed as an ajax response, but it doesn't seem so.

More weird stuff:

If I change the response of "showUploadXmlFileDialog" to "$('Form_XmlFileUploadForm').getPageFromServer();$('Form_EditForm').hide()", I get a "Javascript parse error". Don't know why, Firebug doesn't notice anything about this.

If I uncomment the validator to make the field "File" required, I get the response "validationError('File', '\"Upload File\" wird benötigt.', 'required'); statusMessage('Validierung fehlgeschlagen', 'bad');Behaviour.addLoader(hideLoading); " (sorry for the german strings). It seams as if getXmlFileUploadForm tries to validate the form instead of just printing it. Why?

Any ideas?
Thanks!
craesh

Avatar
craesh

Community Member, 25 Posts

23 June 2010 at 7:57pm

Sorry for bumping this, but I really need some help here...

Avatar
craesh

Community Member, 25 Posts

26 June 2010 at 1:34am

Don't bother, it's not possible with the currect Silverstripe architecture to upload a file in a module and parse it there. You need to use a FileIFrameField (you can't POST files through ajax), that itself will need an existing DataObject (e.g. HomePage) to attach the file to it and do the processing in it's onAfterWrite() method. Sadly, sapphire/core/filesystem/File.php has a very very ugly and hard to find bug so you have to tweek your DataObject instance afterwards. I'll file a bug report as soon as I have the time for it.

I'm really disappointed. I hadn't expect file uploading and handling to be so week and buggy in SS! Really, the only thing you can do is uploading images and displaying them on your pages. Nothing else. For everything else, you'll need to dig deep into core files, find out how stuff works, what's possible and what's not and how you can work around all those bugs...

Guys, please make SS more usable for developers and fight all those bugs before you add more - maybe broken - features.

Now... my customer is waiting, I have to finish that XML file import thing...

creash

Avatar
Willr

Forum Moderator, 5523 Posts

26 June 2010 at 3:12pm

Edited: 26/06/2010 3:13pm

Guys, please make SS more usable for developers and fight all those bugs before you add more - maybe broken - features.

If you can provide a simple to reproduce test case of what you were trying to do please submit it as a bug to open.silverstripe.org. The file attachment functionality is a bit tricky since as you found out it requires objects to be present to load the iframe. Works fine in the context of 'Pages' but anything else its as you found tricky!

A lot of core devs follow the new tickets on open.silverstripe.org more than the discussion forums so if you can provide some code of what you had, the problems and the desired result the issue will hopefully get resolved!

Edit: oh just saw your on 2.3. Before you make a ticket try your code on 2.4. If it works on 2.4 then the answer will be 'upgrade' :D