Post by Jordan on Jan 7, 2011 22:15:35 GMT
This tutorial is a work in progress based off this thread...
This tutorial is for those who want to make their own admin editable code. The code I am going to provide you will cover all the basics, but you may want to take it and remake it your own way.
An admin editable is a code that allows the user to edit itself with a user interface instead of having to modify the code by hand in the header and footer. This is done by taking the user to the header and footer page, but then hiding the table that contains the header and footer and displaying a custom page with input fields that the user can use. When the user is finished editing everything, he or she can hit "Save", and the code will insert the user's input into the header or footer automatically.
To begin, it's best to plan out what we are going to need to make such a code. First, we know we will need to insert links on the main admin page so the admin can click them to go to the custom page to edit the code. So, we will also need to be able to create a custom page and replace the current one. For this custom page, we will need to have the code's current values loaded into the input fields, and finally, we will also need to be able to save the new data.
Knowing this, here are a few internal functions we will need to make.
createPanelLinks(); // Insert links on admin page
createPage(); // Create the page when visisted by admin
loadData(); // Load data into the page for user to edit
saveData(); // Save user's modifications
Another useful function to have is one that detects the header and footer form. This is needed since we need to submit the form when the user hits our custom "Save" button. Also, if the form doesn't exist this function will let us know that the user is not an admin.
findForm();
There are also a few variables we will need. Since it's best to hide our custom page's code in a hidden div, we need to store the ID of the hidden div so we can display it when we need to.
var htmlDivID = "admin_editable";
It's also useful to have a variable that references the admin form, if it exists. This will be set in our findForm() function that we went over above.
var adminForm = null;
Here is where the user's input will be stored. All the information we need for the code to work will be stored in this object, so this is what we will have to update. I've included comments before and after it so it can be easily found by the script when it's updated.
// Start AffData
var data = {
firstField: "value here",
secondField: "second string value"
};
// Stop AffData
Now that we've thought out what we will need to do, we can begin coding. I personally like to contain all my functions in one object, so we are going to create one global object called AdminEditable. Inside this object we am going to create all our private and public functions. The private functions will only be able to be called within the object, and the public functions will be able to be called outside of the object (like by the "Save" button that the user will click). All our variables will be private as well so other scripts can't change their values.
var AdminEditable = function() {
// ID of the div element which contains the custom affiliate page
var htmlDivID = "admin_editable";
// Reference to the admin form if it exists
var adminForm = null;
// Start AffData
var data = {
firstField: "value here",
secondField: "second value here"
};
// Stop AffData
}(); // Execute function/object and create variables and functions
Below is the createPanelLinks() function which I recommend using instead of writing your own. All that you need to edit is the "sectionTitle" variable and the "pageLinks" array. An important detail to notice is the red text which is the link to our custom page. It sends the admin to the main header and footer page, but tags on an additional value to the URL that we can check for to see if the user is on the admin editable page and not just the normal header and footer page.
var createPanelLinks = function() {
var sectionTitle = "Admin Editable Title";
var pageLinks = [
["Manage", "/index.cgi?action=headersfooters2&id=-&aff=manage"],
["Support Board", "http://nightcodes.proboards.com/"]
];
var div_1 = document.createElement("div");
var div_2 = document.createElement("div");
div_2.style.paddingLeft = "35";
var b = document.getElementsByTagName("b");
for(var x = 0; x < b.length; x++){
if(b[x].innerHTML == "Customize Your Forum"){
var parent = b[x].parentNode;
div_1.appendChild(parent.firstChild.cloneNode(true));
div_1.appendChild(document.createElement("b"));
div_1.lastChild.appendChild(document.createTextNode(" " + sectionTitle));
div_1.appendChild(document.createElement("br"));
// If the user has admin access
if(parent.getElementsByTagName("div")[0].innerHTML.match(/>headers\sand\sfooters</i)){
for(var a = 0; a < pageLinks.length; a++){
var link = document.createElement("a");
link.href = pageLinks[1];
link.appendChild(document.createTextNode(pageLinks[0]));
div_2.appendChild(document.createElement("br"));
div_2.appendChild(link);
}
} else {
div_2.appendChild(document.createElement("br"));
div_2.appendChild(document.createTextNode("- No Options Available -"));
}
div_1.appendChild(div_2);
parent.appendChild(div_1);
break;
}
}
}
Below is the createPage() function which hides the header and footer, and then loads the code's data into the custom page's input fields, and then displays the custom page to the user.
var createPage = function() {
// If the user has access to the headers and footers
if(findForm()) {
// Hide the main table
var table = document.getElementsByTagName("table");
for(var x = 1; x < table.length; x++) {
if(table[x].width == "92%" && table[x+2].cellPadding == "4") {
table[x].style.display = "none";
break;
}
}
// Load the data into the data fields
loadData();
// Show the custom table
document.getElementById(htmlDivID).style.display = "";
}
}
Here is the loadData() function which takes the values stored in the "data" object and inserts them into the fields on the custom page. This is called in the createPage() function above.
// Loads the data stored in the JSON "data" object into your custom fields
// which the user can then customize
var loadData = function() {
document.getElementById("firstField").value = data.firstField;
document.getElementById("secondField").value = data.secondField;
}
This function gets called when the user hits "Save". A more in depth explanation of how this function works is in my second post.
var saveData = function() {
if(adminForm) {
// Grab user's input
var field1Value = document.getElementById("firstField").value;
var field2Value = document.getElementById("secondField").value;
// String which will replace what is currently in the main header
var str = "var data = {\n\t\tfirstField: \"" + field1Value + "\",\n\t\tsecondField: \"" + field2Value + "\"\n\t};";
// Regular Expression which matches what we need to replace in the main header
var regex = new RegExp("\\/\\/\\sStart\\sAffData[\n\r\t\\s]*(var[\\s\\S]*}[\n\r\t\\s]*\\/\\/\\sStop\\sAffData","m");
// Match and replace data, and then submit the admin form
if(adminForm.header.value.match(regex)) {
// Use the alert function for testing to see if you are matching the correct text
//alert(RegExp.$1);
adminForm.header.value = adminForm.header.value.replace(RegExp.$1, str);
adminForm.submit();
}
}
}
This function finds the admin form if it exists. It is called in the createPage() function.
// Searches for the admin form. If it does not exist, then the user
// does not have access to the headers and footers.
var findForm = function() {
var f = document.getElementsByTagName("form");
for(var x = 0; x < f.length; x++) {
if(f[x].action.match(/headersfooters3/i)) {
adminForm = f[x];
return true;
}
}
return false;
}
This is a public function that will be called on every page load and will decide what the script should do. The important detail to notice in this function is the location check that we have led the user to with the createPanelLinks() function.
init: function() {
switch(pb_action) {
case "admin": {
createPanelLinks();
break;
}
case "headersfooters2": {
if(location.href.match(/ers2&id=-&aff=manage$/i)) {
createPage();
}
break;
}
}
}
This is our public save function which calls our private save function. Our save button should set this function as its "onclick" value.
// Should be called by your "Save" button on your custom page
save: function() {
saveData();
}
}
Below is the HTML for our custom page.
<div id="affiliate_admin" style="display: none;">
<table width="92%" cellspacing="0" cellpadding="0" align="center">
<tr>
<td valign="top" width="100%">
Affiliate Page<br />
<input type="text" id="firstField" value="" /><br />
<input type="text" id="secondField" value="" /><br />
<input type="button" id="saveButton" value="Save" onclick="NightsAffiliates.save()" />
</td>
</tr>
</table>
</div>
And here is the full script.
Main Header
<script type="text/javascript">
<!--
var AdminEditable = function() {
// ID of the div element which contains the custom page
var htmlDivID = "admin_editable";
// Reference to the admin form if it exists
var adminForm = null;
// Start AffData
var data = {
firstField: "ie",
secondField: "work with me"
};
// Stop AffData
// Hides the admin table containing the headers and footers
// and replaces it with your custom page.
var createPage = function() {
// If the user has access to the headers and footers
if(findForm()) {
// Set page title if you want with document.title = "asdf";
// Hide main table
var table = document.getElementsByTagName("table");
for(var x = 1; x < table.length; x++) {
if(table[x].width == "92%" && table[x+2].cellPadding == "4") {
table[x].style.display = "none";
break;
}
}
// Load the data into the data fields
loadData();
// Show the custom table
document.getElementById(htmlDivID).style.display = "";
}
}
// Loads the data stored in the JSON "data" object into your custom fields
// which the user can then customize
var loadData = function() {
document.getElementById("firstField").value = data.firstField;
document.getElementById("secondField").value = data.secondField;
}
// Extracts the data from the custom fields and then inserts them as a string
// into the main header.
var saveData = function() {
if(adminForm) {
// Grab user's input
var field1Value = document.getElementById("firstField").value;
var field2Value = document.getElementById("secondField").value;
// String which will replace what is currently in the main header
var str = "var data = {\n\t\tfirstField: \"" + field1Value + "\",\n\t\tsecondField: \"" + field2Value + "\"\n\t};";
// Regular Expression which matches what we need to replace in the main header
var regex = new RegExp("\\/\\/\\sStart\\sAffData[\n\r\t\\s]*(var[\\s\\S]*}[\n\r\t\\s]*\\/\\/\\sStop\\sAffData","m");
// Match and replace data, and then submit the admin form
if(adminForm.header.value.match(regex)) {
// Use the alert function for testing to see if you are matching the correct text
//alert(RegExp.$1);
adminForm.header.value = adminForm.header.value.replace(RegExp.$1, str);
adminForm.submit();
}
}
}
// Searches for the admin form. If it does not exist, then the user
// does not have access to the headers and footers.
var findForm = function() {
var f = document.getElementsByTagName("form");
for(var x = 0; x < f.length; x++) {
if(f[x].action.match(/headersfooters3/i)) {
adminForm = f[x];
return true;
}
}
return false;
}
// Inserts panel links on the main admin page
var createPanelLinks = function() {
var sectionTitle = "Affiliate Table";
var pageLinks = [
["Manage", "/index.cgi?action=headersfooters2&id=-&aff=manage"],
["Support Board", "http://nightcodes.proboards.com/"]
];
var div_1 = document.createElement("div");
var div_2 = document.createElement("div");
div_2.style.paddingLeft = "35";
var b = document.getElementsByTagName("b");
for(var x = 0; x < b.length; x++){
if(b[x].innerHTML == "Customize Your Forum"){
var parent = b[x].parentNode;
div_1.appendChild(parent.firstChild.cloneNode(true));
div_1.appendChild(document.createElement("b"));
div_1.lastChild.appendChild(document.createTextNode(" " + sectionTitle));
div_1.appendChild(document.createElement("br"));
// If the user has admin access
if(parent.getElementsByTagName("div")[0].innerHTML.match(/>headers\sand\sfooters</i)){
for(var a = 0; a < pageLinks.length; a++){
var link = document.createElement("a");
link.href = pageLinks[1];
link.appendChild(document.createTextNode(pageLinks[0]));
div_2.appendChild(document.createElement("br"));
div_2.appendChild(link);
}
} else {
div_2.appendChild(document.createElement("br"));
div_2.appendChild(document.createTextNode("- No Options Available -"));
}
div_1.appendChild(div_2);
parent.appendChild(div_1);
break;
}
}
}
// Returns public functions that the outside world can call
return {
// Decides what action to take
init: function() {
switch(pb_action) {
case "admin": {
createPanelLinks();
break;
}
case "headersfooters2": {
if(location.href.match(/ers2&id=-&aff=manage$/i)) {
createPage();
}
break;
}
}
},
// Should be called by your "Save" button on your custom page
save: function() {
saveData();
}
}
}();
//-->
</script>
<div id="admin_editable" style="display: none;">
<table width="92%" cellspacing="0" cellpadding="0" align="center">
<tr>
<td valign="top" width="100%">
Admin Editable Page<br />
<input type="text" id="firstField" value="" /><br />
<input type="text" id="secondField" value="" /><br />
<input type="button" id="saveButton" value="Save" onclick="AdminEditable.save()" />
</td>
</tr>
</table>
</div>
Main Footer
<script type="text/javascript">
<!--
AdminEditable.init();
//-->
</script>
This tutorial is for those who want to make their own admin editable code. The code I am going to provide you will cover all the basics, but you may want to take it and remake it your own way.
An admin editable is a code that allows the user to edit itself with a user interface instead of having to modify the code by hand in the header and footer. This is done by taking the user to the header and footer page, but then hiding the table that contains the header and footer and displaying a custom page with input fields that the user can use. When the user is finished editing everything, he or she can hit "Save", and the code will insert the user's input into the header or footer automatically.
To begin, it's best to plan out what we are going to need to make such a code. First, we know we will need to insert links on the main admin page so the admin can click them to go to the custom page to edit the code. So, we will also need to be able to create a custom page and replace the current one. For this custom page, we will need to have the code's current values loaded into the input fields, and finally, we will also need to be able to save the new data.
Knowing this, here are a few internal functions we will need to make.
createPanelLinks(); // Insert links on admin page
createPage(); // Create the page when visisted by admin
loadData(); // Load data into the page for user to edit
saveData(); // Save user's modifications
Another useful function to have is one that detects the header and footer form. This is needed since we need to submit the form when the user hits our custom "Save" button. Also, if the form doesn't exist this function will let us know that the user is not an admin.
findForm();
There are also a few variables we will need. Since it's best to hide our custom page's code in a hidden div, we need to store the ID of the hidden div so we can display it when we need to.
var htmlDivID = "admin_editable";
It's also useful to have a variable that references the admin form, if it exists. This will be set in our findForm() function that we went over above.
var adminForm = null;
Here is where the user's input will be stored. All the information we need for the code to work will be stored in this object, so this is what we will have to update. I've included comments before and after it so it can be easily found by the script when it's updated.
// Start AffData
var data = {
firstField: "value here",
secondField: "second string value"
};
// Stop AffData
Now that we've thought out what we will need to do, we can begin coding. I personally like to contain all my functions in one object, so we are going to create one global object called AdminEditable. Inside this object we am going to create all our private and public functions. The private functions will only be able to be called within the object, and the public functions will be able to be called outside of the object (like by the "Save" button that the user will click). All our variables will be private as well so other scripts can't change their values.
var AdminEditable = function() {
// ID of the div element which contains the custom affiliate page
var htmlDivID = "admin_editable";
// Reference to the admin form if it exists
var adminForm = null;
// Start AffData
var data = {
firstField: "value here",
secondField: "second value here"
};
// Stop AffData
}(); // Execute function/object and create variables and functions
Below is the createPanelLinks() function which I recommend using instead of writing your own. All that you need to edit is the "sectionTitle" variable and the "pageLinks" array. An important detail to notice is the red text which is the link to our custom page. It sends the admin to the main header and footer page, but tags on an additional value to the URL that we can check for to see if the user is on the admin editable page and not just the normal header and footer page.
var createPanelLinks = function() {
var sectionTitle = "Admin Editable Title";
var pageLinks = [
["Manage", "/index.cgi?action=headersfooters2&id=-&aff=manage"],
["Support Board", "http://nightcodes.proboards.com/"]
];
var div_1 = document.createElement("div");
var div_2 = document.createElement("div");
div_2.style.paddingLeft = "35";
var b = document.getElementsByTagName("b");
for(var x = 0; x < b.length; x++){
if(b[x].innerHTML == "Customize Your Forum"){
var parent = b[x].parentNode;
div_1.appendChild(parent.firstChild.cloneNode(true));
div_1.appendChild(document.createElement("b"));
div_1.lastChild.appendChild(document.createTextNode(" " + sectionTitle));
div_1.appendChild(document.createElement("br"));
// If the user has admin access
if(parent.getElementsByTagName("div")[0].innerHTML.match(/>headers\sand\sfooters</i)){
for(var a = 0; a < pageLinks.length; a++){
var link = document.createElement("a");
link.href = pageLinks[1];
link.appendChild(document.createTextNode(pageLinks[0]));
div_2.appendChild(document.createElement("br"));
div_2.appendChild(link);
}
} else {
div_2.appendChild(document.createElement("br"));
div_2.appendChild(document.createTextNode("- No Options Available -"));
}
div_1.appendChild(div_2);
parent.appendChild(div_1);
break;
}
}
}
Below is the createPage() function which hides the header and footer, and then loads the code's data into the custom page's input fields, and then displays the custom page to the user.
var createPage = function() {
// If the user has access to the headers and footers
if(findForm()) {
// Hide the main table
var table = document.getElementsByTagName("table");
for(var x = 1; x < table.length; x++) {
if(table[x].width == "92%" && table[x+2].cellPadding == "4") {
table[x].style.display = "none";
break;
}
}
// Load the data into the data fields
loadData();
// Show the custom table
document.getElementById(htmlDivID).style.display = "";
}
}
Here is the loadData() function which takes the values stored in the "data" object and inserts them into the fields on the custom page. This is called in the createPage() function above.
// Loads the data stored in the JSON "data" object into your custom fields
// which the user can then customize
var loadData = function() {
document.getElementById("firstField").value = data.firstField;
document.getElementById("secondField").value = data.secondField;
}
This function gets called when the user hits "Save". A more in depth explanation of how this function works is in my second post.
var saveData = function() {
if(adminForm) {
// Grab user's input
var field1Value = document.getElementById("firstField").value;
var field2Value = document.getElementById("secondField").value;
// String which will replace what is currently in the main header
var str = "var data = {\n\t\tfirstField: \"" + field1Value + "\",\n\t\tsecondField: \"" + field2Value + "\"\n\t};";
// Regular Expression which matches what we need to replace in the main header
var regex = new RegExp("\\/\\/\\sStart\\sAffData[\n\r\t\\s]*(var[\\s\\S]*}[\n\r\t\\s]*\\/\\/\\sStop\\sAffData","m");
// Match and replace data, and then submit the admin form
if(adminForm.header.value.match(regex)) {
// Use the alert function for testing to see if you are matching the correct text
//alert(RegExp.$1);
adminForm.header.value = adminForm.header.value.replace(RegExp.$1, str);
adminForm.submit();
}
}
}
This function finds the admin form if it exists. It is called in the createPage() function.
// Searches for the admin form. If it does not exist, then the user
// does not have access to the headers and footers.
var findForm = function() {
var f = document.getElementsByTagName("form");
for(var x = 0; x < f.length; x++) {
if(f[x].action.match(/headersfooters3/i)) {
adminForm = f[x];
return true;
}
}
return false;
}
This is a public function that will be called on every page load and will decide what the script should do. The important detail to notice in this function is the location check that we have led the user to with the createPanelLinks() function.
init: function() {
switch(pb_action) {
case "admin": {
createPanelLinks();
break;
}
case "headersfooters2": {
if(location.href.match(/ers2&id=-&aff=manage$/i)) {
createPage();
}
break;
}
}
}
This is our public save function which calls our private save function. Our save button should set this function as its "onclick" value.
// Should be called by your "Save" button on your custom page
save: function() {
saveData();
}
}
Below is the HTML for our custom page.
<div id="affiliate_admin" style="display: none;">
<table width="92%" cellspacing="0" cellpadding="0" align="center">
<tr>
<td valign="top" width="100%">
Affiliate Page<br />
<input type="text" id="firstField" value="" /><br />
<input type="text" id="secondField" value="" /><br />
<input type="button" id="saveButton" value="Save" onclick="NightsAffiliates.save()" />
</td>
</tr>
</table>
</div>
And here is the full script.
Main Header
<script type="text/javascript">
<!--
var AdminEditable = function() {
// ID of the div element which contains the custom page
var htmlDivID = "admin_editable";
// Reference to the admin form if it exists
var adminForm = null;
// Start AffData
var data = {
firstField: "ie",
secondField: "work with me"
};
// Stop AffData
// Hides the admin table containing the headers and footers
// and replaces it with your custom page.
var createPage = function() {
// If the user has access to the headers and footers
if(findForm()) {
// Set page title if you want with document.title = "asdf";
// Hide main table
var table = document.getElementsByTagName("table");
for(var x = 1; x < table.length; x++) {
if(table[x].width == "92%" && table[x+2].cellPadding == "4") {
table[x].style.display = "none";
break;
}
}
// Load the data into the data fields
loadData();
// Show the custom table
document.getElementById(htmlDivID).style.display = "";
}
}
// Loads the data stored in the JSON "data" object into your custom fields
// which the user can then customize
var loadData = function() {
document.getElementById("firstField").value = data.firstField;
document.getElementById("secondField").value = data.secondField;
}
// Extracts the data from the custom fields and then inserts them as a string
// into the main header.
var saveData = function() {
if(adminForm) {
// Grab user's input
var field1Value = document.getElementById("firstField").value;
var field2Value = document.getElementById("secondField").value;
// String which will replace what is currently in the main header
var str = "var data = {\n\t\tfirstField: \"" + field1Value + "\",\n\t\tsecondField: \"" + field2Value + "\"\n\t};";
// Regular Expression which matches what we need to replace in the main header
var regex = new RegExp("\\/\\/\\sStart\\sAffData[\n\r\t\\s]*(var[\\s\\S]*}[\n\r\t\\s]*\\/\\/\\sStop\\sAffData","m");
// Match and replace data, and then submit the admin form
if(adminForm.header.value.match(regex)) {
// Use the alert function for testing to see if you are matching the correct text
//alert(RegExp.$1);
adminForm.header.value = adminForm.header.value.replace(RegExp.$1, str);
adminForm.submit();
}
}
}
// Searches for the admin form. If it does not exist, then the user
// does not have access to the headers and footers.
var findForm = function() {
var f = document.getElementsByTagName("form");
for(var x = 0; x < f.length; x++) {
if(f[x].action.match(/headersfooters3/i)) {
adminForm = f[x];
return true;
}
}
return false;
}
// Inserts panel links on the main admin page
var createPanelLinks = function() {
var sectionTitle = "Affiliate Table";
var pageLinks = [
["Manage", "/index.cgi?action=headersfooters2&id=-&aff=manage"],
["Support Board", "http://nightcodes.proboards.com/"]
];
var div_1 = document.createElement("div");
var div_2 = document.createElement("div");
div_2.style.paddingLeft = "35";
var b = document.getElementsByTagName("b");
for(var x = 0; x < b.length; x++){
if(b[x].innerHTML == "Customize Your Forum"){
var parent = b[x].parentNode;
div_1.appendChild(parent.firstChild.cloneNode(true));
div_1.appendChild(document.createElement("b"));
div_1.lastChild.appendChild(document.createTextNode(" " + sectionTitle));
div_1.appendChild(document.createElement("br"));
// If the user has admin access
if(parent.getElementsByTagName("div")[0].innerHTML.match(/>headers\sand\sfooters</i)){
for(var a = 0; a < pageLinks.length; a++){
var link = document.createElement("a");
link.href = pageLinks[1];
link.appendChild(document.createTextNode(pageLinks[0]));
div_2.appendChild(document.createElement("br"));
div_2.appendChild(link);
}
} else {
div_2.appendChild(document.createElement("br"));
div_2.appendChild(document.createTextNode("- No Options Available -"));
}
div_1.appendChild(div_2);
parent.appendChild(div_1);
break;
}
}
}
// Returns public functions that the outside world can call
return {
// Decides what action to take
init: function() {
switch(pb_action) {
case "admin": {
createPanelLinks();
break;
}
case "headersfooters2": {
if(location.href.match(/ers2&id=-&aff=manage$/i)) {
createPage();
}
break;
}
}
},
// Should be called by your "Save" button on your custom page
save: function() {
saveData();
}
}
}();
//-->
</script>
<div id="admin_editable" style="display: none;">
<table width="92%" cellspacing="0" cellpadding="0" align="center">
<tr>
<td valign="top" width="100%">
Admin Editable Page<br />
<input type="text" id="firstField" value="" /><br />
<input type="text" id="secondField" value="" /><br />
<input type="button" id="saveButton" value="Save" onclick="AdminEditable.save()" />
</td>
</tr>
</table>
</div>
Main Footer
<script type="text/javascript">
<!--
AdminEditable.init();
//-->
</script>