hi all;
in the demo site changes are:
1- form submition: post and get, try a search for get method and post a news for post method ( you can login using: demo,demo)
2- some redirections, sorry I was unable to do this from whithin the theme, so I made some changes to some files!
3- now you can use inline debug mode and view the resualts in the page. I will set the debug mod so you can test it. the great thing is that we can put the comment: <!--{xo-logger-output}--> in the out put and the debug data will be replaced by this comment.
4- getting left blocks on each request. so whene you go to the news module the block will show you extra menu items.
on theme.html top, now we have:
<{php}>
if(isset($_GET['ajaxpage']) || isset($_POST['ajaxpage'])){
header("Content-type: text/xml; charset=UTF-8");
echo '<?xml version="1.0" encoding="utf-8"?>';
if(isset($_GET['leftBlocks']) || isset($_POST['leftBlocks'])){
echo '<ajax-response>';
echo '<response type="object" id="blocks">';
$sid = 1;
$title = "title";
$content = "Block Content!!";
echo '<blocks sid="leftBlocks">';
foreach($this->_tpl_vars['xoops_lblocks'] as $block){
echo '<block bid="" title="'.$block['title'].'" module="">';
echo '<content>';
echo '<![CDATA['.$block['content'].']]>';
echo '</content>';
echo '</block>';
}
echo '</blocks>';
echo '<dbug>';
echo '<![CDATA[';
<{/php}>
<!--{xo-logger-output}-->
<{php}>
echo ']]>';
echo '</dbug>';
echo '</response>';
echo '</ajax-response>';
}else{
//echo '<!ATTLIST page content CDATA #IMPLIED>';
echo '<ajax-response>';
echo '<response type="object" id="page">';
global $xoopsOption, $xoopsConfig, $xoopsModule, $xoopsRequestUri;
$url = str_replace('?ajaxpage=1','?',($_SERVER['HTTP_HOST'].$xoopsRequestUri));
$url = str_replace('&ajaxpage=1','',$url);
$url = str_replace('?_=','?',$url);
$url = str_replace('&_=','',$url);
$url = str_replace('_=','',$url);
$url = urlencode($url);
if($xoopsModule){
$module = $xoopsModule->getVar('dirname');
}else{
$module = '_nomodule_';
}
//$title = "page title";
$title = $this->_tpl_vars['xoops_sitename'] . ' - ' . $this->_tpl_vars['xoops_pagetitle'];
echo '<page url="'.$url.'" title="'.$title.'" module="'.$module.'" time="" href="">';
echo '<content>';
echo '<![CDATA['.$this->_tpl_vars['xoops_module_header'].$this->_tpl_vars['xoops_contents'].']]>';
echo '</content>';
echo '<dbug url="'.$url.'">';
echo '<![CDATA[';
<{/php}>
<!--{xo-logger-output}-->
<{php}>
echo ']]>';
echo '</dbug>';
echo '</page>';
//echo '<page url="'.$url.'" title="'.$title.'" content="content" />';
echo '</response>';
echo '</ajax-response>';
}
}else{
<{/php}>
the javascript to handle this is:
<script type="text/javascript" src="<{$xoops_imageurl}>Rico/prototype.js"></script>
<script type="text/javascript" src="<{$xoops_imageurl}>Rico/rico.js"></script>
<script language="javascript">
/*
*
* farshid:
* function sanitizeATags
* called when ever we need to make <a> tags call rico functions
* 1- create and attach proper onClick attribute
* 2- remove the href
* 3- some criteria should exict as we need some links not vhanged (ex. <{$xoops_url}>/admin.php)
*
*/
function sanitizeATags(){
/*
* get all <a> tags and put them in atags variable
*/
atags = document.getElementsByTagName('a');
/*
* run throgh all atags, first we will check these:
* atags[i].href != '' a element is linked to somewhere
* atags[i].href.indexOf('admin') == -1 skip admin link(s)
* atags[i].target != '_blank' skip links that will open in new window (ex. banners)
* atags[i].href.indexOf('<{$xoops_url}>') == 0 href attribute starts with our site url
*
*/
for(var i = 0; i < atags.length; i++){
if((atags[i].href != '') && (atags[i].href.indexOf('admin') == -1) && (atags[i].target != '_blank') && (atags[i].href.indexOf('<{$xoops_url}>') == 0)){
/*
*
* create an onClick attribute, set ints value to the proper function call: getPage(url)
* the url comes from atag href attribute.
* after creating it we will append it to the <a> element and set the href attribute: javascript:void(0);
* this will disable the link from going anywhere.
*
* NOTICE: setAttributeNode is not supported in explorer.
*
*/
onClickAttribut = document.createAttribute("onClick");
onClickAttribut.nodeValue = "getPage('"+atags[i].href+"');";
atags[i].setAttributeNode(onClickAttribut);
//atags[i].setAttribute(onClickAttribut);
atags[i].href = "javascript:void(0);";
}
}
}
/*
*
* farshid:
* function sanitizeFormTags
* called when ever we need to make <form> tags call rico functions
*
*/
function sanitizeFormTags(){
/*
* get all <form> tags and pit them in formtags variable
*/
formtags = document.getElementsByTagName('form');
/*
* run throgh all formtags:
*/
for(var i = 0; i < formtags.length; i++){
/*
* first we will check if the form action is compelete, many forms
* hase relative actions to the page they are loaded in.
* this needs some work, to do its job properly.
*
* NOTICE: setAttributeNode is not supported in explorer.
*
*/
if(formtags[i].getAttribute('action').indexOf('http://')!=0){
actionAttribut = document.createAttribute("action");
actionAttribut.nodeValue = '<{$xoops_url}>/'+formtags[i].getAttribute('action');
formtags[i].setAttributeNode(actionAttribut);
}
/*
*
* Next we will check for these:
* formtags[i].getAttribute('method') != '' form hase some methods!
* formtags[i].getAttribute('method') == 'get' in this part we are going to sanitize forms with ger method
* formtags[i].getAttribute('action').indexOf('<{$xoops_url}>' action attrin starts with our site url
*
*/
if((formtags[i].getAttribute('method') != '') && (formtags[i].getAttribute('method') == 'get') && (formtags[i].getAttribute('action').indexOf('<{$xoops_url}>') == 0)){
/*
* we are in our form with get methis, lets take all form elements
*/
formElements = formtags[i].elements;
/*
* loop throgh all elements to find submit and button types.
*/
for(var j =0; j<formElements.length; j++){
/*
* in case we found a submit type, we will change the type to button (we do not want the form to be submited!)
* formElements[j].getAttribute('type') == 'submit' type is submit
* !formElements[j].getAttribute('onclick') we will sanitize if there is no onClick attribute
* formElements[j].getAttribute('onclick').indexOf('submitFormGet')==0 and if it has some onClick it should be the one we have added.
* so what! lets do it again, if we are on another page and the forms
* array (document.forms) is changed then the button will submit another form.
*/
if((formElements[j].getAttribute('type') == 'submit') && (!formElements[j].getAttribute('onclick') || (formElements[j].getAttribute('onclick').indexOf('submitFormGet')==0))){
/*
* so we should change this submit type, and add the onClick attribute to it.
*/
typeAttribut = document.createAttribute("type");
typeAttribut.nodeValue = "button";
formElements[j].setAttributeNode(typeAttribut);
/*
* this button will call submitFormGet(form)
* the form is the one we are in now: document.forms[i]
*/
onClickAttribut = document.createAttribute("onclick");
onClickAttribut.nodeValue = "submitFormGet(document.forms["+i+"]);";
formElements[j].setAttributeNode(onClickAttribut);
/*
* so what if we find a button that we have alredy sanitized, but as we are in another page the refrence to form
* element is wrong! lets fix it now:
*/
}else if((formElements[j].getAttribute('type') == 'button') && (!formElements[j].getAttribute('onclick') || (formElements[j].getAttribute('onclick').indexOf('submitFormGet')==0))){
onClickAttribut = document.createAttribute("onclick");
onClickAttribut.nodeValue = "submitFormGet(document.forms["+i+"]);";
formElements[j].setAttributeNode(onClickAttribut);
}
}
/*
* this part will do the same thing with the post method forms.
* this part should be combined with the previous part.
*/
}else if((formtags[i].getAttribute('method') != '') && (formtags[i].getAttribute('method') == 'post') && (formtags[i].getAttribute('action').indexOf('<{$xoops_url}>') == 0)){
formElements = formtags[i].elements;
for(var j =0; j<formElements.length; j++){
if((formElements[j].getAttribute('type') == 'submit')){
typeAttribut = document.createAttribute("type");
typeAttribut.nodeValue = "button";
formElements[j].setAttributeNode(typeAttribut);
if(!formElements[j].getAttribute('onclick')){
onClickAttribut = document.createAttribute("onclick");
/*
* some forms are posted based on the submitter name so lets pass the submiter name
* to the poster function.
*/
if(document.createAttribute("name")){
onClickAttribut.nodeValue = "submitFormPost(document.forms["+i+"],this.name);";
}else{
onClickAttribut.nodeValue = "submitFormPost(document.forms["+i+"],'');";
}
formElements[j].setAttributeNode(onClickAttribut);
}else{
alert(formElements[j].getAttribute('onclick'));
/*
onClickAttribut = document.createAttribute("onclick");
onClickAttribut.nodeValue = "submitFormPost(document.forms["+i+"]);";
formElements[j].setAttributeNode(onClickAttribut);
*/
}
}else if((formElements[j].getAttribute('type') == 'button') && (formElements[j].getAttribute('onclick').indexOf('location=') == 0)){
//alert(formElements[j].getAttribute('onclick'));
onClickAttribut = document.createAttribute("onclick");
onClickAttribut.nodeValue = "submitFormPostByLocation(document.forms["+i+"],this);";
formElements[j].setAttributeNode(onClickAttribut);
}
}
}
}
}
/*
*
* function sanitizeModuleATags(string: module directory name)
* just like sanitizeATags function, but for links in a module
* called when ever we need to make <a> tags in a module
* call rico functions
* 1- create and attach proper onClick attribute
* 2- remove the href
* 3- some criteria should exict as we need some links not vhanged (ex. <{$xoops_url}>/admin.php)
*
* NOTIC: sanitizeATags function should always be called befor calling this function.
*
*/
function sanitizeModuleATags(moduleDir){
/*
* just get tags in the ajax_content part.
*/
modulearea = document.getElementById('ajax_content');
atags = modulearea.getElementsByTagName('a');
for(var i = 0; i < atags.length; i++){
/*
* (atags[i].href != '') we have some href to handle
* atags[i].target != '_blank' page is not opening in a new window
* atags[i].getAttribute('target') != '_blank' I don't know why I put this here!
* atags[i].href.indexOf('<{$xoops_url}>/modules/'+moduleDir) == 0 the link is in the module directory
* atags[i].href.indexOf('userinfo.php') != -1 the link is not pointing to user info, if it is so ot os alredy sanitized
*/
if((atags[i].href != '') && (atags[i].target != '_blank') && (atags[i].getAttribute('target') != '_blank') && ((atags[i].href.indexOf('<{$xoops_url}>/modules/'+moduleDir) == 0) || (atags[i].href.indexOf('userinfo.php') != -1))){
onClickAttribut = document.createAttribute("onClick");
onClickAttribut.nodeValue = "getPage('"+atags[i].href+"');";
atags[i].setAttributeNode(onClickAttribut);
//atags[i].setAttribute(onClickAttribut);
atags[i].href = "javascript:void(0);";
}else if((atags[i].href.indexOf('<{$xoops_url}>') == 0) && (atags[i].getAttribute('target') != '_blank')){
onClickAttribut = document.createAttribute("onClick");
xoopsUrl = '<{$xoops_url}>';
onClickAttribut.nodeValue = "getPage('<{$xoops_url}>/modules/"+moduleDir+atags[i].href.substring(xoopsUrl.length,atags[i].href.length)+"');";
atags[i].setAttributeNode(onClickAttribut);
//atags[i].setAttribute(onClickAttribut);
atags[i].href = "javascript:void(0);";
}
}
}
/*
* Create a page_object object which is responsible for handling our pages
* This part has been modified from rico examples.
*/
var page_obj = Class.create();
/*
* our page hase some attributes:
* url: page url
* title: page title that will be replaced to show current page title in the browser
* module: in the page is a module page: module directory name, else this will be: "_nomodule_"
* time: if the page is a redirecting page, the time to wait before redirecting
* href: the url we will redirect to after (time) seconds
* content: page content
*/
page_obj.attributes = [ "url", "title", "module", "time", "href", "content" ];
page_obj.prototype = {
initialize: function(url) {
},
ajaxUpdate: function(ajaxResponse) {
this.placePage(ajaxResponse.childNodes);
},
placePage: function(page_responce) {
/*
* page_responce is the xml part we have generated for the page;
* it is somthing like this:
*
* <page url="page url" title="page Title" module="module directory" time="" href="">
* <content>
* <![CDATA[not well formed html content here]]>
* </content>
* <dbug url="localhost%3A81%2Fxoops1016ajax%2F%3F">
* <![CDATA[not well formed html dbug data here]]>
* </dbug>
* </page>
*
* page content and debug data will be loaded as CDATA section.
* other data (attributes) are automaticaly mapped by Rico.
*/
var pageHolder = '';
/*
* get title, url and module directory.
*/
pageTitle = page_responce[0].getAttribute('title');
pageUrl = page_responce[0].getAttribute('url');
pageModule = page_responce[0].getAttribute('module');
/*
* get redirect time and url, and see if we should do redirect the page!
*/
redirectTime = page_responce[0].getAttribute('time');
redirectUrl = decodeURIComponent(page_responce[0].getAttribute('href'));
shouldRedirect = ((redirectTime != '') && (redirectUrl != ''));
/*
* get page content and debug data
*/
pageHolder += page_responce[0].childNodes[0].childNodes[0].nodeValue;
debugData = page_responce[0].childNodes[1].childNodes[0].nodeValue;
/*
* set page title, content and debug data.
*/
document.title = pageTitle;
document.getElementById('ajax_content').innerHTML = pageHolder;
document.getElementById('debugWindowDebugArea').innerHTML = 'Debug Data for URL: '+decodeURIComponent(pageUrl)+'n'+debugData;
document.getElementById('debugWindowDebugArea').style.visibility = 'visible';
/*
* if we are in a module sanitize module tags, else
* do normal sanitize.
*/
if(pageModule != '_nomodule_'){
sanitizeModuleATags(pageModule);
}else{
sanitizeATags();
}
/*
* sanitze forms
*/
sanitizeFormTags();
/*
* inform user that the page is loaded and
* give him/her a link to the main url.
*/
document.getElementById('pageLoadingMessage').innerHTML = 'main page url: <a href="http://'+decodeURIComponent(pageUrl)+'" target="_blank">http://'+decodeURIComponent(pageUrl) + '</a>';
/*
* if we should redirect, call the getPage(url) function after time*1000 milsec
*/
if(shouldRedirect){
window.setTimeout("getPage('"+redirectUrl+"')",redirectTime*1000);
}
}
}
var page_obj;
/*
* this is the same as page object, just for blocks,
* right now just left blocks.
*
*/
var block_obj = Class.create();
block_obj.attributes = [ "bid", "title", "module", "content" ];
block_obj.prototype = {
initialize: function(url,blockSide) {
this.url = url;
this.blockSide = blockSide;
},
ajaxUpdate: function(ajaxResponse) {
this.placeBlock(ajaxResponse.childNodes);
},
placeBlock: function(block_responce) {
var blockHolder = '';
blocks = block_responce[0].childNodes;
elementToAdd = document.getElementById('leftcolumn');
elementToAdd.innerHTML = '';
for(var i=0;i<blocks.length;i++){
addBlockToPage(this.blockSide,blocks[i].attributes['title'].nodeValue,blocks[i].childNodes[0].childNodes[0].nodeValue);
}
sanitizeATags();
sanitizeFormTags();
document.getElementById('blockLoadingMessage').innerHTML = '';
}
}
var block_obj;
function addBlockToPage(blockSide,blockTitle,blockContent){
switch(blockSide){
case 'Left':
blockElement = document.getElementById('leftcolumn');
break;
}
newBlockTitleDiv = document.createElement('div');
classAttrib = document.createAttribute("class");
classAttrib.nodeValue = "blockTitle";
newBlockTitleDiv.setAttributeNode(classAttrib);
newBlockTitleDiv.innerHTML = blockTitle;
blockElement.appendChild(newBlockTitleDiv);
newBlockContentDiv = document.createElement('div');
classAttrib = document.createAttribute("class");
classAttrib.nodeValue = "blockContent";
newBlockContentDiv.setAttributeNode(classAttrib);
newBlockContentDiv.innerHTML = blockContent;
blockElement.appendChild(newBlockContentDiv);
}
function registerAjaxPage(url) {
document.getElementById('pageLoadingMessage').innerHTML = 'Loading Page, Use this link if the page failed Loading: <a href="'+url+'" target="_blank">'+url+'</a>';
ajaxEngine.registerRequest( 'getPage', url );
//ajaxEngine.registerAjaxElement( 'ajax_content' );
ajaxEngine.registerAjaxObject( 'page', new page_obj(url) );
}
function getPage(url) {
registerAjaxPage(url);
ajaxEngine.sendRequest( 'getPage', "ajaxpage=1" );
getLeftBlocks(url);
}
function registerAjaxBlocks(url,blockSide) {
document.getElementById('blockLoadingMessage').innerHTML = ' and Loading '+blockSide+' Blocks...';
if(blockSide == 'Left'){
ajaxEngine.registerRequest( 'getLeftBlocks', url );
}
ajaxEngine.registerAjaxObject( 'blocks', new block_obj(url,blockSide) );
}
function getLeftBlocks(url){
registerAjaxBlocks(url,'Left');
params_arr = Array("ajaxpage=1","leftBlocks=1");
params = params_arr.join('&');
ajaxEngine.sendRequest( 'getLeftBlocks', {parameters:params} );
}
function submitFormGet(form){
var formElements = form.elements;
var formParams = Array('ajaxpage=1');
for(var j =0; j<formElements.length; j++){
switch(formElements[j].type){
case 'text':
case 'hidden':
formParams.push(encodeURIComponent(formElements[j].getAttribute('name'))+"="+encodeURIComponent(formElements[j].value));
break;
case 'checkbox':
if(formElements[j].checked){
formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value));
}
break;
case 'select-one':
formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value));
break;
}//switch
}
registerAjaxPage(form.getAttribute('action'));
var params = formParams.join('&');
ajaxEngine.sendRequest( 'getPage', {parameters:params} );
}
function submitFormPost(form,elementName){
var formElements = form.elements;
var formParams = Array('ajaxpage=1');
if(elementName != ''){
formParams.push(elementName+'='+elementName);
}
elements = '';
for(var j =0; j<formElements.length; j++){
elements += formElements[j].type+'n';
if(formElements[j].getAttribute('name') != null){
switch(formElements[j].type){
case 'text':
case 'hidden':
case 'select-one':
case 'textarea':
case 'password':
formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value));
break;
case 'checkbox':
case 'radio':
if(formElements[j].checked){
formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value));
}
break;
case 'file':
formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value));
break;
}//switch
}
}
registerAjaxPage(form.getAttribute('action'));
var params = formParams.join('&');
ajaxEngine.sendRequest( 'getPage', {method:'post',parameters:params} );
}
function submitFormPostByLocation(form,element){
//var formElements = form.elements;
//var Location = element.value;
//var formParams = Array('ajaxpage=1');
alert('called');
//elements = '';
/*
for(var j =0; j<formElements.length; j++){
//elements += formElements[j].type+'n';
switch(formElements[j].type){
case 'text':
case 'hidden':
formParams.push(encodeURIComponent(formElements[j].getAttribute('name'))+"="+encodeURIComponent(formElements[j].value));
break;
case 'checkbox':
if(formElements[j].checked){
formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value));
}
break;
case 'select-one':
formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value));
break;
}//switch
}
*/
//formParams.push(encodeURIComponent(element.getAttribute('name'))+"="+encodeURIComponent(formElements[j].value));
//alert(elements);
//registerAjaxPage(form.getAttribute('action'));
//var params = formParams.join('&');
//alert(params);
//ajaxEngine.sendRequest( 'getPage', {method:'post',parameters:params} );
}
</script>
The code has some comments that I wish helps you.
I am going to do something new: bringing the admin area to XOOPS front side, just like liferay portal.
and another idea is a full flash theme based on this aproach, I am thinking of this, any ideas? or do you think this is good or bad?
there is some other changes in the theme, I will put the file for download as soon as possible.
and thanks for all your comments;
@highlander
I found the article in French, so I need the English version.