Drag and Drop dashboard using jquery and save state of each change

Tags

, , , , , ,


I found some solution to make drag and drop on dashboard. After drag and drop we need to keep save the state for each user so when user login they can get their own dashboard what they saved last time.
First download and add jquery and jqueryui to your page

Lets assume we have 3 column, here is the code

<!-- This is first column -->
<div id="column_1" class="column">
  <div id="item_1" class="dragbox">
    <!-- this one is first item of 1st column -->
    <h2>Title for 1</h2>
    <div class="dragbox-content">Your contents goes here...</div>
  </div>
  <div id="item_2" class="dragbox">
    <!-- this one is second item of 1st column -->
    <h2>Title for 2</h2>
    <div class="dragbox-content">Your contents goes here...</div>
  </div>
  <div id="item_3" class="dragbox">
    <!-- this one is third item of 1st column -->
    <h2>Title for 3</h2>
    <div class="dragbox-content">Your contents goes here...</div>
  </div>
</div>

<!-- 2nd Column -->
<div id="column_2" class="column">
  <div id="item_4" class="dragbox">
   <!-- this one is 4th item of 2nd column -->
   <h2>Title for 4</h2>
   <div class="dragbox-content">Your contents goes here...</div>
  </div>
  <div id="item_5" class="dragbox">
    <!-- this one is 5th item of 2nd column -->
   <h2>Title for 5</h2>
   <div class="dragbox-content">Your contents goes here...</div>
  </div>
</div>

<!-- Third column -->
<div id="column_3" class="column">
  <div id="item_6" class="dragbox">
    <!-- this one is 6th item of 2nd column -->
    <h2>Title for 6</h2>
    <div class="dragbox-content">Your contents goes here...</div>
  </div>
  <div id="item_7" class="dragbox">
    <!-- this one is 7th item of 2nd column -->
    <h2>Title for 7</h2>
    <div class="dragbox-content">Your contents goes here...</div>
  </div>
</div>

Make sure your column id is unique and your all item id under any column should be unique. Here is use id like “item_1”, “item_2″……”item_5″…etc.
Here is the css code

.column{
	width:32%;
	margin-right:.5%;
	float:left;
        min-height: 300px;
}
.column .dragbox{
	margin:5px;
	background:#fff;
	position:relative;
	border:1px solid #ddd;
}
.column .dragbox h2{
	margin:0;
	font-size:12px;
	padding:5px;
	background:#f0f0f0;
	color:#000;
	border-bottom:1px solid #eee;
	font-family:Verdana;
	cursor:move;
}
.dragbox-content{
	background:#fff;
	min-height:100px; margin:5px;
	font-family:'Lucida Grande', Verdana; font-size:0.8em; line-height:1.5em;
}
.column  .placeholder{
	background: #f0f0f0;
	border:2px dashed #883533;
}

You can customized css based on your design but make sure that your .column class should have min-height or height if you remove that then you cann’t drag the item.
h2 used for your dragable item,
.placeholder is used when you drag some box and place holder will showing where it need to be place.
here is the javascript code

  $('.column').sortable({
	connectWith: '.column',
	handle: 'h2',
	cursor: 'move',
	placeholder: 'placeholder',
	forcePlaceholderSize: true,
	opacity: 0.4,
        stop: function(event, ui){
            //saveState();
        }
})
.disableSelection();

h2 used as handle, you can change it, we’ll discuss about stop in next section.

your outcome something like this, here when I trying to drag item 2

Now In this way we just drag and drop but when we need to save each state and when user logout and again login the dashboard should be same when they logout, I used here php and mysql to save state,
Here is the database table

CREATE TABLE IF NOT EXISTS `dashboard_items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `column_no` int(11) NOT NULL,
  `order` int(11) NOT NULL,
  `widget` char(100) COLLATE utf8_unicode_ci NOT NULL,
  `last_update_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

‘id’ is used for item id (e.g. item_1, item_2….. item_8 etc.)
‘column_no’ is column number here we used just 3 column
‘order’ it used for item order in a column,
‘widget’ it uses when we do for loop we might need to call some widget which we need to put here..
‘user_id’ if you have multiple user and you can keep user id and save its state.

now, how we fetch the data

$column = array();
for($i = 1, $i <= 3; $i++){
$sql = "SELECT `DashboardItem`.`id`, `DashboardItem`.`column_no`, `DashboardItem`.`order`, `DashboardItem`.`widget`, `DashboardItem`.`last_update_date`, `DashboardItem`.`user_id` FROM `dashboard_items` AS `DashboardItem` WHERE `DashboardItem`.`column_no` = $i and  `DashboardItem`.`user_id` = 1 ORDER BY `DashboardItem`.`order` ASC";
$column[$i] = $this->DashboardItem->query($sql); // here is used cakephp syntex which will output like the following section 
}

the output for one column

Array
(
    [0] => Array
        (
            [DashboardItem] => Array
                (
                    [id] => 3
                    [column_no] => 1
                    [order] => 2
                    [widget] => 0
                    [last_update_date] => 2012-02-17 11:41:49
                    [user_id] => 1
                )
        )
    [1] => Array
        (
            [DashboardItem] => Array
                (
                    [id] => 2
                    [column_no] => 1
                    [order] => 1
                    [widget] => 0
                    [last_update_date] => 2012-02-17 11:41:49
                    [user_id] => 1
                )
        )
    [2] => Array
        (
            [DashboardItem] => Array
                (
                    [id] => 1
                    [column_no] => 1
                    [order] => 0
                    [widget] => 0
                    [last_update_date] => 2012-02-17 11:00:42
                    [user_id] => 1
                )
        )
)

Now here is the html code

	<div class="column" id="column_1">
		<?php foreach($column[1] as $col){ ?>
                <div class="dragbox" id="item_<?php echo $col['DashboardItem']['id']?>" >
			<h2> Call your header based on the widget</h2>
			<div class="dragbox-content" >
                            put your contents based on your widget
			</div>
		</div>
                <?php } ?>
	</div>
	<div class="column" id="column_2" >
		<?php foreach($column[2] as $col){ ?>
                <div class="dragbox" id="item_<?php echo $col['DashboardItem']['id']?>" >
			<h2>put your contents based on your widget</h2>
			<div class="dragbox-content" >
                             put your contents based on your widget
			</div>
		</div>
                <?php } ?>
	</div>
	<div class="column" id="column_3" >
		<?php foreach($column[3] as $col){ ?>
                <div class="dragbox" id="item_<?php echo $col['DashboardItem']['id']?>" >
			<h2>put your contents based on your widget</h2>
			<div class="dragbox-content" >
                            put your contents based on your widget
			</div>
		</div>
                <?php } ?>
	</div>
<div id='result'></div>

Now we have to pass ajax requset based on the change of dahboard which will keep your dashboard same

   $('.column').sortable({
	connectWith: '.column',
	handle: 'h2',
	cursor: 'move',
	placeholder: 'placeholder',
	forcePlaceholderSize: true,
	opacity: 0.4,
        stop: function(event, ui){  
            saveState();
        }
})
.disableSelection();

function saveState(){
    var items = [];
    // traverse all column div and fetch its id and its item detail. 
    $(".column").each(function(){
        var columnId = $(this).attr("id");
        $(".dragbox", this).each(function(i){ // here i is the order, it start from 0 to...
           var item = {
               id: $(this).attr("id"),
               column_no: columnId,
               order: i
           }
           items.push(item);
        });
        
    });
    $("#results").html("loading..");
    var shortorder = {items : items};
        $.ajax({
          url: "<?php echo "/dashboard_item.php"; ?>",
          async: false, 
          data: shortorder,
          dataType: "html",
          type: "POST",
          success: function(html){
            $("#results").html(html);
          }
        });    
}

saveState() is calling when you do any drag and drop of any item.
under saveState() it fetch the data based on column and make an array which we passing to ajax request then we save

$data = $_POST;
foreach($data as $d){
   $item_no = split("_",$d['id']); //split item_3 to get 3 and that is our item table id 
   $d['id'] = $item_no[1];
            
   $col_no = split("_", $d['column_no']); //split 
   $d['column_no'] = $col_no[1];
   
    $this->Dashboard->save($d); // I used cakephp syntax here, it will update database  You have to update each row based on the column no and user id
}

In this way we can keep save the drag and drop state. 🙂

Remove Skype Plugin from browser using jQuery

Tags

, , ,


I got some problem after installing the skype plugins on my browser. This plugin always convert to a call now button to numbers, sometime some number is not a phone number, which cause problem for our web design. I found a solution which we can used for stop converting the call now button for numbers on the webpage.

<script src="YOUR_JQUERY_PAT/jquery.min.js" language="javascript"></script>
<script language="javascript">
	$(document).ready(function() {
		window.setTimeout(function() {
			$('.skype_pnh_container').html('');
			$('.skype_pnh_print_container').removeClass('skype_pnh_print_container');
		}, 700);
	});
</script>

Its work for me. I found it form here

Multiple line html code assign to a javascript variable/ assign cakephp element to a javascript variable

Tags

, ,


I was working with google map api, I have task to make a infowindow for a marker. I faced some problem when I assigned multiple line code to a javascript variable. I tried to put a html code to a javascrpt variable which will use for info window.

I need to put block of html code (cakephp element) to a variable. if we do like the following

<script>
var infowindow = '<div class="map_info_content">
    <table cellpadding="3" cellspacing="3">
        <tr>
            <td colspan="2">
                <h1 class="map_title"><?=$map_title?></h1>
            </td>
        </tr>
        <tr>
            <td align="left" valign="top">
                <img src="<?=$imgurl?>" style="<?=$style_img?>" /> 
            </td>
            <td align="left" valign="top">
                <p>
                    <?=$msg?>
                </p>
            </td>
        </tr>
    </table>';
</script>

Its not not working, we need to put a slash / each end of line or need to write infowindow += “” for each line.
Now If we keep that html code to a cakephp element and just call the element and make it json_encode it work or keep this in to a php variable and make it json encode it working lets see

<?php
    $html = '<div class="map_info_content">
    <table cellpadding="3" cellspacing="3">
        <tr>
            <td colspan="2">
                <h1 class="map_title">Title</h1>
            </td>
        </tr>
        <tr>
            <td align="left" valign="top">
                <img src="info.jpg" style="" /> 
            </td>
            <td align="left" valign="top">
                <p>
                    HERE IS YOUR MSG
                </p>
            </td>
        </tr>
    </table>';
// Now make it json encode
$html = json_encode($html);
?>
// Now Assign it to a javascript variable
<script>
 var infowindow = <?=$html?> 
// OR if cakephp element
 var infowindow = <?=json_encode($this->element("infowindow"))?>

</script>

json_encode is very useful method to working like this.
🙂

jquery UI tab – ajax loading CKEDITOR in a tab and some issues

Tags

, , ,


I tried to load CKEDITOR in a jquery tab via ajax. I got problem that only first time the ckeditor is working but when I click on other tab and again got o ckeditor tab its not working. in Load section for tab I put the following code.

load: function(event, ui) {
  if(ui.index == 3){ // Checked tab no 4
    var instance = CKEDITOR.instances['reditor']; // reditor is text area id, check if instances exists for readitor or not 
    if(instance){ 
       CKEDITOR.remove(instance); //if existed then remove it
    }
    CKEDITOR.replace( 'reditor' ); // Create instance for 'reditor'
 }
}

in this way we can get rid the problem of “CKEditor instance already exists”

Here is whole configuration

$(document).ready(function () {
           var $tabs = $("#tabs").tabs({ 
                                
                                alignment: "top",
                                spinner : false,
                                ajaxOptions: {
                                    error: function( xhr, status, index, anchor ) {
                                                    $( anchor.hash ).html( "Couldn't load this tab. Please try again.");
                                                },
                                    complete: function(){
                                        
                                        
                                    }
                                    
                                },
                                load: function(event, ui) {
                                    if(ui.index == 3){
                                        var instance = CKEDITOR.instances['reditor'];
                                        if(instance){
                                            CKEDITOR.remove(instance);
                                        }
                                    }
                                },
                                select: function(e, ui){
                                            $(ui.panel).html('<img src="img/ajax_loader.gif" />'); // Loader after click on each tab
                                        }
                                
                                });
           $tabs.tabs('select', <?=$tab_no?>); // used for selected default tab
           
        });
        

Here is HTML/PHP (I used cakephp syntax for url ) used “TEXT” in a link to show the loading text on tab otherwise it will not show the loading tabl

<div id="tabs">
    <ul>
        <li>
            <?=$html->link("<span>Information</span>", array("controller" => "listings", "action" => "information", $id), array("escape" => false, "title" => "Information"))?>
            
        </li>
        <li>
            <?=$html->link("<span>Detail</span>", array("controller" => "listings", "action" => "detail", $id), array("escape" => false))?>
        </li>
        <li>
            <?=$html->link("<span>Peoples</span>", array("controller" => "listing", "action" => "peoples", $id), array("escape" => false))?>
        </li>
        <li>
            <?=$html->link("<span>Enhance</span>", array("controller" => "listings", "action" => "enhance", $id), array("escape" => false))?>
       </li>
    </ul>
 </div>

In this way I did and it work for me 🙂

cakephp- CONCAT in query, Virtual Fields and make a drop down

Tags

, ,


I need to make a dropdown list of a staff. In dorpdown i need to put last name and first name. I already have a column in database name which contain first name and last name. But i need to show order last name then first name.

I tied to put CONCAT in query its working but the array result not showing properly. In this case I found that if i put a virtual fields in model that help me to fetch proper data.

In model

   var $virtualFields = array('dropdown_name' => 'CONCAT(Staff.last_name, " ", Staff.first_name)');

In controller query:

// Generate list
 $staff_list =  $this->Staff->find("list", array(
                                                        "fields" => array("id", "dropdown_name"),
                                                        "order" => array("Staff.name ASC"),
                                                        "conditions" => array('Staff.status' => '1')
                                                        ));

The above code give me the proper list of staff.
In view to generate dropdown

    echo $form->input("Reports.staff_id", 
                                array(
                                    'options' => $staff_list, 
                                    'empty' => '--Please Select--' ,
                                    'label'=> false, 
                                    ));    

In this way we can generate dropdown with different column in a one field.

The following I tried

          $staff_list = $this->Staff->find("list", array(
                                                        "fields" => array("Staff.id", "CONCAT(`Staff`.`last_name`, ' ', `Staff`.`first_name`)"),
                                                        "order" => array("AgencyStaff.name ASC"),
                                                        "conditions" => array('Staff.status' => '1')
                                                        ));

The query is runing properly but the result array doesn’t keep the CONACT fields, it only keep the id balnk.

But I run the query in cakephp and check what actually give it the result .

$list = $this->Staff->query("SELECT `Staff`.`id` , CONCAT( `Staff`.`last_name` , ' ', `Staff`.`first_name` ) 
                                        FROM `staffs` AS `Staff`
                                            WHERE `Staff`.`status` =1
                                            ORDER BY `Staff`.`name` ASC");

Result is the following

Array
(
    [0] => Array
        (
            [Staff] => Array
                (
                    [id] => 5
                )

            [0] => Array
                (
                    [CONCAT( `Staff`.`last_name` , ' ', `Staff`.`first_name` )] => Johnson Ashley
                )

        )
................
................

Thats why cakephp couldn’t make the proper array if we use their ORM.

I tried to use CONCAT( `Staff`.`last_name` , ‘ ‘, `Staff`.`first_name` ) as `Staff`.`name`
but it still not working.

SO I choose the virtual fields concept and it working properly for me 🙂

trace visitor location based on their geolocation- how to

Tags

, , ,


I tried to find out a solution how we can block or trace visitor location and based on that location we do some action

First you have to use 3rd party api to get visitor location. The following url will give you the detail.
http://ipinfodb.com/ip_location_api.php

Lets assume the visitor ip is 180.234.12.237 (you’ll get key from that website)
http://api.ipinfodb.com/v3/ip-city/?key=&ip=180.234.12.237

Its has some response format that is xml, json, raw, just you have to pass a get variable &format=json

  if (getenv(HTTP_X_FORWARDED_FOR)){
        $pipaddress = getenv(HTTP_X_FORWARDED_FOR);
        $ipaddress = getenv(REMOTE_ADDR);
        //echo "Your Proxy IPaddress is : ".$pipaddress. "(via $ipaddress)" ;
    } else {
        $ipaddress = getenv(REMOTE_ADDR);
        //echo "Your IP address is : $ipaddress";
    }     

    

$_API = "83838s88s4e0a65jhk80246d77d8s5s3988d9fb1asdkf000asd8fslasdlfasdf6s9sce";
$_URL = "http://api.ipinfodb.com/v3/ip-country/?key=$_API&ip=$ipaddress&format=json";

$data = file_get_contents($_URL);

$data = json_decode($data);
if(isset($data->statusCode) && $data->statusCode == "OK"){
    if(isset($data->countryCode) && ($data->countryCode != "USA" )) || $data->countryCode != "BD")){
        header("Location:http://www.yourdomain.com/geolocation.php");     
        exit;
    }
}

In this way we can find out the country, city, post code, time zone etc. we can block or trace visitors in our website.

.htaccess killing 3 hours

Tags

, , ,


I’m working in cakephp for last two years, I developed and hosted many times, during hosting I got many problem all these are .htaccess related.

Today I tried to host one of my project, I created a server on rackspace cloud and installing all features apache, mysql, phpmyadmin and configure everything, I installed sugarcrm there and it worked, but when I tried to run my cakephp project, its always displaying “PAGE NOT FOUND”. the rewrite mdoule was on and i checked it working for others,

I checked apache error/access log, not clue found, doing some google no result, but I never give-up again trying to do some google got a reference in drupal site and check my apache configuration.

Only one thing I left in apache configuration.

// Open the apache site available
sudo nano /etc/apache2/sites-available/default

The article says that for URL rewriting we need to make “AllowOverride none” to “AllowOverride All”

I open that file and changed it.

<VirtualHost *:80>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www
        <Directory />
                Options FollowSymLinks
                AllowOverride All 
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All 
                Order allow,deny
                allow from all
        </Directory>
...... 
......
...

Done, went to my site and its working properly, 🙂

Access session data in a model -cakephp

Tags

, , ,


Sometime we may need auth data for inserting in bforeSave method, i know it break the MCV rule but we sometime we need it for doing faster.

I used it in beforeSave method in a module

function beforeSave(){
   App::import('Component', 'SessionComponent'); 
   $session = new SessionComponent(); 
   // say we just retrieve the auth data
   $auth = $session->read("Auth.user");
  // here i used to add row value
  $this->data['ModelName']['field_name'] = $auth['login_user_id'];
   
  return true;
}

In this way we can use full session component data here. 🙂

cakephp ajax pagination using jquery

Tags

, , ,


I tried to use cakephp default ajax pagination, it seems not working with me. I tried with different way.

The following code using for pagination.

<div class="paginator">
        <?php echo $paginator->first(' First ', null, null, array('class' => 'disabled')); ?>
        <?php echo $paginator->prev('Previous ', null, null, array('class' => 'disabled')); ?>
        <?php echo $paginator->numbers(); ?>
       <?php echo $paginator->next(' Next ', null, null, array('class' => 'disabled')); ?>
        <?php echo $paginator->last(' Last ', null, null, array('class' => 'disabled')); ?>
</div>   

Now below that code I used the following java script code

<script>
    $(document).ready(function(){
        $(".paginator a").click(function(){
            $("#updated_div_id").load(this.href);
            return false;
        })
    });
</script>

Here, I just fire an event on click under paginator div, once you click on a link under that div, it fetch the url (this.herf) and calling page using ajax, You must prepared the controller for ajax based.

for example your controller calling ‘ajax_pages’ action.

function ajax_pages(){
        $this->layout = 'ajax';
        $this->paginate = array(
                                'order' => array('Module.created_date' => 'desc'), 
                                'recursive' => -1,
                                "limit" => PAGINATION_LIMIT
                                );
        
        $conditions['Module.module_type'] = $module_type;
        $data = $this->paginate("Module", $conditions);
        $this->set(compact("data"));  
}

Its work for me 🙂