How to make CJUIDatePicker in a form in Yii – three-step example

I’m new to Yii php framework and I’m fiddling about it. I created a database and a date column in it, and pregenerated (with Gii – recommending this!) the controller and views for it.

However, the Create/Update forms made my input field for the date a text field.

So here is a quick recipe on how to use CJUIDatePicker widget (jQuery UI DatePicker object) for it:

1) Open the _form.php file in the view for your desired class. For me, it was in protected/views/guest/.

2) Find your row. My gii-generated form had columns in div’s and each div (each column) had three rows:

<div class="row">
 <?php echo $form->labelEx($model,'created'); ?>
 <?php echo $form->textField($model,'created'); ?>
 <?php echo $form->error($model,'created'); ?>
 </div>

3) Remove the middle row and replace it with the widget you want:

 

$this->widget('zii.widgets.jui.CJuiDatePicker', array(
// 'name'=>'birthdate',
 'name'=>"Guest[created]", // the name of the field
 'value'=>$model->created,  // pre-fill the value
 // additional javascript options for the date picker plugin
 'options'=>array(
 'showAnim'=>'fold',
 'dateFormat'=>'yy-mm-dd',  // optional Date formatting
 'debug'=>true,
),
 'htmlOptions'=>array(
 'style'=>'height:20px;'
 ),
 ));

There, that worked for me, and I’ll update this post when I run into bugs.

Posted in JavaScript | Leave a comment

How to understand Javascript closures

In writing my programs with JavaScript, I never really completely understood the closure idea. I still think I don’t, but here is how I will try to explain it to myself. The idea and code used is from one of the Youtube videos of Douglas Crockfords ‘the good parts’.

We can start with a simple example. We want to turn digits into strings, something like this:

var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'ate', 'nine' ];
function  digit_name(n) {
return names[n];
}
digit_name(4); // returns ‘four’.

This code will run ok, but it has a problem: the names array is global. Any other JavaScript on the page can break our code by writing over our “names” variable.

So we could do this:

function  digit_name(n) {
var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'ate', 'nine' ];  // this is now private to our function
return names[n];
}
digit_name(4); // returns ‘four’.

This code is better – we have a self-sufficient function, without polluting global namespace. But now, every time we call the function, we re-initialize our names array.

How to avoid it? Here is an example:

var digit_name = function () {
var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'ate', 'nine' ];
return function (n) {
return names[n];
}
}

This is now much better. What happens on executing? First, a private array is initialized and stored to memory. Then we return a function that will look up our names array and find the result.

Wait, what?

Well – the array is initialized and left in memory. And each time somebody calls our returned function from digit_name(n), that returned function will look up into the now-enclosured (in lack of better term) array.
It means that our later function call doesn’t execute digit_name – it only executes the anonymous function we returned. And that function has access to our private variable.
So the anonymous inner function will execute when needed, but our array is only initialized once (and held in a closure).

So the module pattern for creating stuff in closures should be something like this:

var singleton = function () {
var privateVariable; // only created once
function privateFunction() {  // only created once

};
return {
methodOne: function (param) { // this is exported out once.
// so when we call singleton.methodOne(param)
// later, the private stuff above is already there and
// within closure
},
methodTwo: function(a, b) { // another public method
….
},
publicInt: 10
};
}

// now calling and instantiating the object will have the object being created, private vars and methods left there, and public stuff exposed to us.

I think I got it right, hopefully this will help me (and possibly others) in the future.

Posted in JavaScript | Leave a comment

Dropbox referal link

Well, everybody on the planet (well at least a hundred milion of us) uses Dropbox. So do I, the free version. But with it, I can get some extra free space, and I could surely use it. So if you don’t already have a dropbox account, you can use my referal link: http://db.tt/hacs7Mn

It’s a win/win/win – they get a customer, you get an account, and I get extra 250MB space.

Posted in General | Leave a comment

How to add a second taskbar to your other monitor in twinview in ubuntu

I have an Ubuntu workstation at work with a nvidia graphics card and dual monitors in Twinview mode (meaning, they act like one large desktop, except that the full screen apps take only one monitor, if I got it right).

Anyway, I wanted to add a taskbar to my other monitor – mainly because I wanted a second taskbar with the window list. My main problem was that I had no apparent way to add any panels to the second monitor – they all ended up on the primary.

Well, here is how one can do it:

1.) Right click on anywhere on the old panels and  click “New Panel”

2.) hold down ALT + Drag the new panel to any monitor/location.

3.) Right click on the new panel and click “Add to Panel”

4.) Now you can add the window list (Right-click -> Add -> Window List) or anything you need here.

5) Click Close.

Posted in linux | Tagged dual-monitor, taskbar, twinview, ubuntu | Leave a comment

World, meet Isaac! Isaac, meet World!

I’ve just been given an amazing present and a huge responsibility: Isaac. Isaac is a cactus, I don’t know the sort yet, but I will find out, I hope. Now I need to take care of it and make sure it grows old :-)

Anyway, here is a low quality photo I made with my cellphone. I hope you like Isaac!

Isaac the Cactus

Isaac the CactusIsaac the Cactus

Posted in General | Tagged cactus | Leave a comment

Baked Catfish with Mushroom Sauce Recipe in JavaScript

This is a small demo why programmers can usually get to be good cooks! Here is how you cook a nice catfish in some mushroom and wine sauce in JavaScript.

Disclaimer: I’m not a JavaScript ninja, and this was written in parallel!! to making the actual dinner, so I know it could be vastly improved. You should probably not follow the JavaScript examples from the script, especionally the pausing time! I just didn’t have the time to implement proper event engine that would run on its own.

First, the last part of the script (link) (which runs without errors in node.js v0.6.5 and Chrome Developer Console):

// Lets cook!!
ingreedients.push({"catfish filets": "2"});
ingreedients.push({"soy souce": "1 tsp"});
ingreedients.push({"pepper": "2 pinch"});
ingreedients.push({"wine": "1/2 cup"});
ingreedients.push({"pepper": "1 pinch"});
ingreedients.push({"salt": "1 pinch"});
ingreedients.push({"sliced mushrooms": "2 cups"});
ingreedients.push({"garlic": "2 pcs"});
ingreedients.push({"olive oil": "2 tsp"});
pan.heat(180);
pan.add(ingreedients.next());
pan.heat(90);
pan.add(ingreedients.next());
pan.heat(120);
pan.add(ingreedients.next());
pan.braise();
pan.add(ingreedients.next());
pan.add(ingreedients.next());
pan.simmer(10);
pan.add(ingreedients.next());
pan.simmer(6);
bakingPan.heat(120);
bakingPan.add(ingreedients.next());
bakingPan.add(ingreedients.next());
bakingPan.add(ingreedients.next());
bakingPan.bake(25);
bakingPan.serve();
console.log(log);

The last part – console.log – outputs all this stuff:
Warming up pan for 180 seconds…
…done
Adding 2 tsp olive oil to pan.
Warming up pan for 90 seconds…
…done
Adding 2 pcs garlic to pan.
Warming up pan for 120 seconds…
…done
Adding 2 cups sliced mushrooms to pan.
Braising olive oil, garlic, sliced mushrooms…
…done
Adding 1 pinch salt to pan.
Adding 1 pinch pepper to pan.
Simmering ingreedients olive oil, garlic, sliced mushrooms, salt, pepper in the pan for 10 minutes…….
…done
Adding 1/2 cup wine to pan.
Simmering ingreedients olive oil, garlic, sliced mushrooms, salt, pepper, wine in the pan for 6 minutes…….
…done
Warming up pan for 120 seconds…
…done
Adding 2 pinch pepper to pan.
Adding 1 tsp soy souce to pan.
Adding 2 catfish filets to pan.
Baking ingreedients in the oven (olive oil, garlic, sliced mushrooms, salt, pepper, wine, pepper, soy souce, catfish filets) for 25 minutes…….
…done
The dish is ready. Bon apetit!)


Of course, here’s the initialization stuff: 

var log = 'Replaying log: ';
var ingreedients = [];
ingreedients.next = function () {
  return ingreedients.pop();
}

var pan = new Object();
pan.add = function (ingreedient) {
  var i;
  if (!this.stuff) {
    this.stuff = '';
  }
  for (i in ingreedient) {
    if ('' != this.stuff) {
      this.stuff = this.stuff + ', ';
    }
    this.stuff = this.stuff + i;
  }
  console.log('Adding ' + ingreedient[i] + ' ' + i + ' to pan.');
  log += '\r\nAdding ' + ingreedient[i] + ' ' + i + ' to pan.';
}

pan.braise = function(seconds) {
  var start = new Date(), end, milis;
  // bad bad mojo but no time for writitng asynchronous calls and parallelization and stuff now
  console.log('Braising ' + this.stuff + '...');
  log += '\r\nBraising ' + this.stuff + '...';
  if (seconds < 40) {
    milis= seconds * 117;
    console.log('(I will compress time a little bit, of course)');
  } else {
    milis = 4000;
    console.log('(I will compress time a little bit, of course)');
  }
  do { end = new Date();}
  while (end - start < milis);
  console.log('...done');
  log += '\r\n...done';
}
pan.heat = function(seconds) {
  var start = new Date(), end, milis;
  // bad bad mojo but no time for writitng asynchronous calls and parallelization and stuff now
  console.log('Warming up pan for ' + seconds + ' seconds...');
  log += '\r\nWarming up pan for ' + seconds + ' seconds...';
  if (seconds < 40) {
    milis= seconds * 117;
    console.log('(I will compress time a little bit, of course)');
  } else {
    milis = 4000;
    console.log('(I will compress time a little bit, of course)');
  }
  do { end = new Date();}
  while (end - start < milis);
  console.log('...done');
  log += '\r\n...done';
}
pan.simmer = function (minutes) {
  var start = new Date(), end, milis;
  // bad bad mojo but no time for writitng asynchronous calls and parallelization and stuff now
  seconds = minutes * 60;
  milis= seconds * 1000;
  console.log('Simmering ingreedients ' + this.stuff + ' in the pan for ' + minutes + ' minutes...');
  log += '\r\nSimmering ingreedients ' + this.stuff + ' in the pan for ' + minutes + ' minutes...';
  var tickerTime = 600;
  var ticker = start;
  var breakAt = 2500;
  do {
    end = new Date();
    if (end - start > breakAt) {
      console.log('Compressing time a bit..........');
      start = end + 2500;
    }
    if (end - ticker > tickerTime) {
      ticker = end;
      console.log('.');
      log += '.';
    }
  }
  while (end - start < milis);
  console.log('...done');
  log += '\r\n...done';
}
pan.bake = function (minutes) {
  var start = new Date(), end, milis;
  // bad bad mojo but no time for writitng asynchronous calls and parallelization and stuff now
  seconds = minutes * 60;
  milis= seconds * 1000;
  console.log('Baking ingreedients in the oven (' + this.stuff + ') for ' + minutes + ' minutes...');
  log += '\r\nBaking ingreedients in the oven (' + this.stuff + ') for ' + minutes + ' minutes...';
  var tickerTime = 600;
  var ticker = start;
  var breakAt = 2500;
  do {
    end = new Date();
    if (end - start > breakAt) {
      console.log('\r\nCompressing time a bit..........');
      start = end + 2500;
    }
    if (end - ticker > tickerTime) {
      ticker = end;
      console.log('.');
      log += '.';
    }
  }
  while (end - start < milis);
  console.log('...done');
  log += '\r\n...done';
}
pan.serve = function() {
  console.log('The dish is ready');
  log += '\r\nThe dish is ready. Bon apetit!)';
}
var bakingPan = new Object(pan);
bakingPan.stuff = '';

Posted in General | Tagged catfish, javascript | Leave a comment

A smallish bitbucket trick: handling more then one account

Today I had to think on how to handle two separate bitbucket.org git accounts without conflicts.

I have my private bitbucket account: zladuric. There I have some play-code – thing to play with.  I also have a company bitbucket account: zduric. There’s the company central-sort-of code repository.

Now, I can checkout something from my company account:

git@bitbucket.org:zduric/myoffice.git

I need to enter my details, username, email, password and all. But now I also have a private account.

git@bitbucket.org:zladuric/jam.git

How to handle that?

Well, that’s where SSH comes in. I already use SSH’s config file to handle authentication. I have a ssh key and config section in my .ssh/config, and I use it like this:

Host bitbucket.org
        User git
        HostName bitbucket.org
        PreferredAuthentications publickey
        IdentityFile ~/.ssh/id_rsa

Now, I just added another section, to ssh config file, with my git-specific key:

Host bitbuck
        User git
        HostName bitbucket.org
        PreferredAuthentications publickey
        IdentityFile ~/.ssh/git_id_rsa

There is one last detail:

When checking out private files, I use

git@bitbucket.org:zladuric/jam.git

And for company repo, I can safely use:

git@bitbuck:zduric/myoffice.git

SSH can handle the rest. Pretty nifty, huh?

Posted in linux | Tagged bitbucket.org, git, ssh | Leave a comment

Gmail Cheat Sheet (iliti Gmail šalabahter)

Ovdje se nalazi verzija za ispis Googlove Help stranice za Gmail.

Tražio sam način kako u gmailu nešto napraviti automatski i u googlanju sam naletio na tu stranicu. Pa sam si ju isprintao i zalijepio na stol, dok ne zapamtim one najvažnije.

Posted in General | Leave a comment

Vim search and replace throughout the file

Zlatko,

When you want to search and replace every instance of a string1 with string2 in a file, don’t look up the web to get the correct syntax for the milionth time.

Just write down:

:%s/string1/string2/g

Sincerely,

Zlatko

Posted in linux | Leave a comment

YUI handlers and their scope

I’m creating an Alfresco dashlet right now, which has a YUI Button in it, which in turn creates a YUI DataSource and invokes a YUI Dialog, which gets created and also renders a nice YUI DataTable based on the datasource above.

Now, I’ve ran into a question: when I wanted to “handle” the submit from that dialog, I wanted to reach the datasource. But the handler functions’ this was the Dialog instance, not the object holding it (and the datasource). So I googled and I found out how to do it.

Instead of

var dialogConfig = { buttons: [
{"text": "OK", handler: handleSubmit, isDefault: true},
{"text": "Cancel", handler: handleCancel}
]};

you give the config objects’ handler property another object:

{fn:this.handleSubmit, obj: this, scope: this}

This way you pass the scope and the object (which doesn’t have to be this, by the way, it can be something custom).

And then I remembered that in YUI Ajax callback configuration, you also use this format. Again YUI proves to be really well thought! So I’m going to use it more from now on, I think.

 

Posted in YUI | Leave a comment