Well, that was annoying.
Background
I'm working with Codeigniter-Bonfire to create a web application. CI-Bonfire is an MVC framework that lets you put views within views by calling modules::run('path/to/controller/function', $arg).
Error
I kept getting this error whenever I tried to call modules::run on a function that I know works.
Fatal error: Cannot redeclare function_name() (previously declared in /path/to/view_file.php:2) in /path/to/view_file.php on line 15.
Line 2 in view_file.php is where I declare the function. Line 15 is where the function ends. I know this error comes up because I'm using view_file.php twice somehow and that's why the function is getting redeclared. But where??
Back to the controller I go and I noticed that I forgot a simple else statement.
In CI-Bonfire, you can print out a view either by itself (using the standard base_url/module/controller/function/args path) or by calling $this->load->view('view_folder/view_file', $args_array) in the controller if you've set some variable to true.
My rendering function looked like this:
if ($hmvc)
$this->load->view('view_folder/view_file', $args_array);
Template::render();
But it should've looked like this:
if ($hmvc)
$this->load->view('view_folder/view_file', $args_array);
else
Template::render();
Phew!
Tuesday, January 29, 2013
Tuesday, November 20, 2012
Using jQuery .on() rather than .onClick on dynamically generated buttons
Last week, I was beating my head over why the .click() event wasn't working with a dynamically generated button. My setup was that the buttons were given the class 'do_this' and the javascript looked like:
At first I thought maybe it was because the code wasn't inside $(document).ready(), so I put it inside one. Didn't work. Then I tried assigning the attribute and value 'onClick="runThisFunction()"' to the button instead. Still no go. (I also thought maybe I should define the Javascript functions after the buttons were generated, so I did just that. I'm not sure why it didn't work, though. It could be because the JS that rendered the buttons happened through a .post call.)
Then my co-worker pointed me to the jQuery .on() method. Surprise, surprise: it worked! The code looks like this now:
The jQuery documentation goes on to explain why .on() works and none of my previous attempts did:
So with that in mind, happy coding!
$('.do_this').click(function(){ /* insert code here */ }; At first I thought maybe it was because the code wasn't inside $(document).ready(), so I put it inside one. Didn't work. Then I tried assigning the attribute and value 'onClick="runThisFunction()"' to the button instead. Still no go. (I also thought maybe I should define the Javascript functions after the buttons were generated, so I did just that. I'm not sure why it didn't work, though. It could be because the JS that rendered the buttons happened through a .post call.)
Then my co-worker pointed me to the jQuery .on() method. Surprise, surprise: it worked! The code looks like this now:
$(document).on("click", '.add_contact', function(event) { /* insert code here */ });The jQuery documentation goes on to explain why .on() works and none of my previous attempts did:
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.See? I put everything inside
document so the class was already rendered when the Javascript bound the class to the click event.So with that in mind, happy coding!
Labels:
bonfire,
code igniter,
event handlers,
javascript,
jquery,
onclick
Saturday, October 13, 2012
Bringing up a jQuery dialogue before going to a controller
Currently, I'm using CodeIgniter/Bonfire for a website that does your basic CRUD operations. One of the functionalities the user wanted was a confirmation dialogue that the user really wanted to delete an item, which corresponds to an entry in the database. My problem was that, while I knew how to bring up jquery dialogue boxes, I wasn't sure how to redirect the dialogue to the controller that would actually delete that item from the database. My solution was to use the "id" attribute of my delete button.
While iterating through the items returned from the table, print out the name of the item and a delete button beside it. The delete button is really an anchor tag styled to look like a button.
Notice that I didn't use the href attribute. What I would've put in href, I instead put in id. If I hadn't, I wouldn't be able to call the jquery dialogue because the page would instead go to the href link.
Whenever this anchor tag is clicked, this piece of javascript would be run:
It's basic jquery, but the key is the assignment of the anchor tag's id attribute. The above code says: when an anchor tag with class 'delete' is clicked, grab that anchor tag's ID attribute and store it in variable "dest". Then look for an html element with the id "confirm_delete" and display it in a dialogue with the following height, width, and buttons: Yes and No.
Just so you know, the div with id = confirm_delete is somewhere on the page with this code:
If the user clicks on the "Yes" button, then the user will be redirected to the controller that will actually delete the item. If he chooses "No", then the dialogue just closes.
While iterating through the items returned from the table, print out the name of the item and a delete button beside it. The delete button is really an anchor tag styled to look like a button.
< a class='btn delete' id='".site_url()."modulename/controllername/function_name/{$item->id}'>Delete< /a>
Notice that I didn't use the href attribute. What I would've put in href, I instead put in id. If I hadn't, I wouldn't be able to call the jquery dialogue because the page would instead go to the href link.
Whenever this anchor tag is clicked, this piece of javascript would be run:
$('a.delete').click(function() {
var dest = $(this).attr('id');
$('#confirm_delete').css("display", "block").dialog({
height: 150,
width: 350,
modal: true,
buttons:
{
Yes: function(){
window.location = dest;
},
No: function(){
$(this).dialog('close');
}}}).dialog('open');});
It's basic jquery, but the key is the assignment of the anchor tag's id attribute. The above code says: when an anchor tag with class 'delete' is clicked, grab that anchor tag's ID attribute and store it in variable "dest". Then look for an html element with the id "confirm_delete" and display it in a dialogue with the following height, width, and buttons: Yes and No.
Just so you know, the div with id = confirm_delete is somewhere on the page with this code:
< div id="confirm_delete" style="display: none;" title="Remove item"> Are you sure you want to remove this item? </ div>
If the user clicks on the "Yes" button, then the user will be redirected to the controller that will actually delete the item. If he chooses "No", then the dialogue just closes.
Labels:
bonfire,
code igniter,
controller,
dialogue,
jquery,
php
Monday, July 9, 2012
Uploading a custom header image to the twentyeleven theme in Wordpress
This is more of a note to myself.
Right now, I am tasked with customizing the twentyeleven theme into another theme , and it involves turning off the rotating header images. After unsuccessfully doing a walkthrough of the associated code (that begins in header.php with a call to header_image()), I found the functions.php file under wp-content/themes/. In the twentyeleven_setup() function, I found a call to register_default_headers, which takes in an associative array. I only need one header image, so I deleted all but one key-value pair, renamed the key to something that made sense, and pointed the 'url' key to the photo filename. Now, although I haven't deleted any of the other header images from the directory structure, the code will only pick up the one header image I registered.
Right now, I am tasked with customizing the twentyeleven theme into another theme , and it involves turning off the rotating header images. After unsuccessfully doing a walkthrough of the associated code (that begins in header.php with a call to header_image()), I found the functions.php file under wp-content/themes/
Wednesday, March 28, 2012
Self-note: error concerning NetFx40_IIS_schema_update.xml
So a while ago, while trying to restart IIS, I got an annoying error that said C:\Windows\System32\inetsrv\config\schema\NetFx40_IIS_schema_update.xml wasn't a well-formed xml file. Fine. I checked it, and it was indeed malformed--it contained only nulls.
Fix this by deleting the goshdarn file.
Fix this by deleting the goshdarn file.
Tuesday, October 18, 2011
Getting Thunderbird to work with distribution.ini
The bug I'm working on is the ability to customize vanilla Thunderbird with a group of settings (through distribution.ini). For those who do not know, Thunderbird is Mozilla's open source mail client. (Mozilla = makers of Firefox). I'm far from done. This entry is a culmination of what I have learned so far.
Checkout the repo
I am working with Fedora, so I use yum. I followed the build and configure instructions from here. In a nutshell, here are the steps to cloning the comm-central (Thunderbird) repo:
1) yum install mercurial - to get Mercurial, a version control tool.
2) Create a file called ".hgrc" in your home directory and put these in it:
[ui]
username=Firstname Lastname
merge=internal:merge
[diff]
git=1
showfunc=1
unified=8
[defaults]
commit=-v
Note: Obviously, replace Firstname, Lastname, and my.email... with your information.
3) Make sure you're in the directory that you want to put the repo in (for example, your home dir) then checkout the repo:
hg clone http://hg.mozilla.org/comm-central/ src-thunderbird
So now you should have a "src-thunderbird" folder in your current directory.
Building Thunderbird
1) Go to your src-thunderbird directory (cd src-thunderbird).
2) Create a .mozconfig file. (I use vi, so vi .mozconfig). This file will contain your build configurations for Thunderbird. The contents of mine are:
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-tbdebug
ac_add_options --enable-application=mail
ac_add_options --enable-debug
ac_add_options --disable-optimize
"obj-tbdebug" is the directory where all my object files will end up (you can change what you call yours). I will refer to this as objdir, from now on. The second line says, build me Thunderbird. The third line is because I need debugging printouts. The fourth line I just threw in for good measure. You can read more about configuration options here.
3) Build Thunderbird! "make -f client.mk build" (while still in src-thunderbird). This step will take a while (more than a half hour in my case).
4) Once the build is done, run Thunderbird with ./objdir/mozilla/dist/bin/thunderbird. Since we configured this build with the debug option, you will see a lot of printouts at your terminal.
Updating the repository
Make sure you're in the src-thunderbird directory. On the terminal, execute python client.py checkout. Re-build again.
Modifying the source files
The source files are everything outside your src-thunderbird file. Everything in it are your object files. When you modify your source files, you need to re-create your object files. You can run make -f client.mk build again (in your src-thunderbird dir), and it won't take as long as the first time.
If you changed files in only one directory, you can re-make only that directory. For example, if you changed files only in ~/src-thunderbird/mail/components, run make -C objdir/mail/components.
Getting distribution.ini working
1) This is a sample distribution.ini. This file must be placed in objdir/mozilla/dist/bin/distribution.
2) Add "distribution.js \" to the EXTRA_JS_MODULES section of Makefile.in (which resides in ~/src-thunderbird/mail/base/modules).
3) distribution.js should be in ~/src-thunderbird/mail/base/modules. I copied and modified the Firefox version. (Code referring to bookmarks and livemarks were ripped out.) I also changed the name of the object it exported to something like TBDistCustomizer.
(Note: JS modules have EXPORTED_SYMBOLS at the start of the file. This is as opposed to components files (which are also JS), which do not.)
4) cd to objdir/mail/base/modules and type "make".
5) Modify mailGlue.js (in ~/src-thunderbird/mail/components) so that:
(a) It would import distribution.js (Components.utils.import("resource:///modules/distribution.js");); and
(b) it would create an instance of TBDistCustomizer. This intance can now be used to call the code in distribution.js that actually changes prefs (applyPrefDefaults).
Hitting the brick wall
So now I've come to the point where preferences set in distribution.ini are being set in Thunderbird, but there is a catch: some prefs are set properly, while others are duplicated. For example, mail.phishing.detection.enabled is set correctly, but something like network.cookie.lifetimePolicy instead becomes duplicated, with one version having the default and the other having the value that was set in distribution.ini.
I am still trying to figure out why this is so...
Climbing the brick wall
The problem was that distribution.ini doesn't like spaces around the "=" sign. network.cookie.lifetimePolicy = 1 should be network.cookie.lifetimePolicy=1.
Thanks to...
The MailDev team at Mozilla! In particular Standard8 and sid0 for helping me get started.
Checkout the repo
I am working with Fedora, so I use yum. I followed the build and configure instructions from here. In a nutshell, here are the steps to cloning the comm-central (Thunderbird) repo:
1) yum install mercurial - to get Mercurial, a version control tool.
2) Create a file called ".hgrc" in your home directory and put these in it:
[ui]
username=Firstname Lastname
merge=internal:merge
[diff]
git=1
showfunc=1
unified=8
[defaults]
commit=-v
Note: Obviously, replace Firstname, Lastname, and my.email... with your information.
3) Make sure you're in the directory that you want to put the repo in (for example, your home dir) then checkout the repo:
hg clone http://hg.mozilla.org/comm-central/ src-thunderbird
So now you should have a "src-thunderbird" folder in your current directory.
Building Thunderbird
1) Go to your src-thunderbird directory (cd src-thunderbird).
2) Create a .mozconfig file. (I use vi, so vi .mozconfig). This file will contain your build configurations for Thunderbird. The contents of mine are:
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-tbdebug
ac_add_options --enable-application=mail
ac_add_options --enable-debug
ac_add_options --disable-optimize
"obj-tbdebug" is the directory where all my object files will end up (you can change what you call yours). I will refer to this as objdir, from now on. The second line says, build me Thunderbird. The third line is because I need debugging printouts. The fourth line I just threw in for good measure. You can read more about configuration options here.
3) Build Thunderbird! "make -f client.mk build" (while still in src-thunderbird). This step will take a while (more than a half hour in my case).
4) Once the build is done, run Thunderbird with ./objdir/mozilla/dist/bin/thunderbird. Since we configured this build with the debug option, you will see a lot of printouts at your terminal.
Updating the repository
Make sure you're in the src-thunderbird directory. On the terminal, execute python client.py checkout. Re-build again.
Modifying the source files
The source files are everything outside your src-thunderbird file. Everything in it are your object files. When you modify your source files, you need to re-create your object files. You can run make -f client.mk build again (in your src-thunderbird dir), and it won't take as long as the first time.
If you changed files in only one directory, you can re-make only that directory. For example, if you changed files only in ~/src-thunderbird/mail/components, run make -C objdir/mail/components.
Getting distribution.ini working
1) This is a sample distribution.ini. This file must be placed in objdir/mozilla/dist/bin/distribution.
2) Add "distribution.js \" to the EXTRA_JS_MODULES section of Makefile.in (which resides in ~/src-thunderbird/mail/base/modules).
3) distribution.js should be in ~/src-thunderbird/mail/base/modules. I copied and modified the Firefox version. (Code referring to bookmarks and livemarks were ripped out.) I also changed the name of the object it exported to something like TBDistCustomizer.
(Note: JS modules have EXPORTED_SYMBOLS at the start of the file. This is as opposed to components files (which are also JS), which do not.)
4)
5) Modify mailGlue.js (in ~/src-thunderbird/mail/components) so that:
(a) It would import distribution.js (Components.utils.import("resource:///modules/distribution.js");); and
(b) it would create an instance of TBDistCustomizer. This intance can now be used to call the code in distribution.js that actually changes prefs (applyPrefDefaults).
So now I've come to the point where preferences set in distribution.ini are being set in Thunderbird, but there is a catch: some prefs are set properly, while others are duplicated. For example, mail.phishing.detection.enabled is set correctly, but something like network.cookie.lifetimePolicy instead becomes duplicated, with one version having the default and the other having the value that was set in distribution.ini.
I am still trying to figure out why this is so...
Climbing the brick wall
The problem was that distribution.ini doesn't like spaces around the "=" sign. network.cookie.lifetimePolicy = 1 should be network.cookie.lifetimePolicy=1.
The MailDev team at Mozilla! In particular Standard8 and sid0 for helping me get started.
Labels:
distribution.ini,
mozilla,
open source,
thunderbird
Wednesday, June 15, 2011
Mozilla XPCom
Here is the link to a list of ALL the XPCOM contract ID's/components and interfaces are: http://www.oxymoronical.com/experiments/xpcomref/
I am currently working on creating an addon that will always take settings from Internet Explorer and set the same prefs for Firefox. Still in the research stages, tho.
I am currently working on creating an addon that will always take settings from Internet Explorer and set the same prefs for Firefox. Still in the research stages, tho.
Subscribe to:
Posts (Atom)