RSS
 

Archive for the ‘Programming’ Category

jQuery 筆記 – 同步兩個 option buttons 的值

25 Feb

情境 :
在一連串 table 的網頁介面. 如果把 option button 部分設計在最下方. 那當table資料很多的時候就要一直捲動捲到最下方. 小不方便. 所以還要在多設計一個 option button 在網頁的最上方. 但是在同一個 form 如果裡面變數名稱命名不一樣的名稱到 option button 上. 那代表要在 php 裡面去處理那個兩個變數名稱. 也要處理使用者是按了上面的 action button 還是下面的 action button. 看起來有點麻煩.

解法 :
為了簡化這個問題, 我使用 jquery 幫忙同步兩個option buttons 的值. 下列是html部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<form method="POST" action="#">
      <h3>Available actions
      <select id="paction" name="paction">
        <option value="on">Power On</option>
 
        <option value="off">Power Off</option>
        <option value="soft">Graceful Shutdown</option>
        <option value="reset">Reset System (warm boot)</option>
        <option value="cycle">Power Cycle System (cold boot)</option>
      </select>
      <input type="submit" name="submit" value="Perform action"></h3>
omit......
      <h3>Available actions
      <select id="paction2" name="paction">
        <option value="on">Power On</option>
 
        <option value="off">Power Off</option>
        <option value="soft">Graceful Shutdown</option>
        <option value="reset">Reset System (warm boot)</option>
        <option value="cycle">Power Cycle System (cold boot)</option>
      </select>
      <input type="submit" name="submit" value="Perform action"></h3>
</form>

命名了兩個 option buttons 的 id 名稱. 但那兩個 option button 的 name 是一樣的. 然後再使用下列 jquery 語法. 就可以將這兩個不同的 option buttons 同步.

1
2
3
4
5
6
7
    $("#paction").change(function() {
        $("#paction2").val($("#paction").val());
    });
 
    $("#paction2").change(function() {
        $("#paction").val($("#paction2").val());
    });

其實只要把下面的值同步成真正要處理的值就可以了. 因為網頁 submit 後. 同名稱變數(paction)的話是看最後一個值. 但是為了要求完美. 所以我在把下面的 option button 同步回去第一個 option button

最後看一下 DEMO

 

jQuery 筆記 – 找出每個特定字串開頭的div進行處理

24 Feb

情境 :
我想列出一連串 servers 開關機狀態. 還有電流大小. 當然我可以直接顯示在網頁上. 但是顯示那樣的網頁可能會花 15~20秒才有辦法把每一台 servers 的狀態讀回來. 在等待的過程.網頁是白色的畫面. 這樣看起來好像網頁當掉了. 所以想說先把html table layout 顯示出來. 在透過 jquery 顯示後面比較花時間的資料. 所以必須要針對不同的 servers 進行狀態查詢. 這樣的顯示方式看起來比較不像是當掉. XD

解法 :
假設我有下列 html 然後想針對每個 foo_ 開頭的 div 進行處理.

1
2
3
4
5
<div id="foo_1"></div>
<div id="foo_2"></div>
<div id="foo_3"></div>
<div id="foo_4"></div>
<div id="foo_5"></div>

當然可以先用 php 把個別的變數輸出到 javascrpit 內的某個變數. 然後再個別去處理. 但是這樣太肉腳了.所以用下列 jquery 方式處理.

1
2
3
    $("div[id^='foo_']").each(function() {
      $(this).text("我的div名稱是 " + $(this).attr('id') + ".");
    });

這樣就會列出下列結果

我的div名稱是 foo_1.
我的div名稱是 foo_2.
我的div名稱是 foo_3.
我的div名稱是 foo_4.
我的div名稱是 foo_5.

這樣你應該有感覺了吧? 再來就可以在 function 內處理..看是要針對 1 2 3 4 5 不同的名稱給予不同的處理. 例如用 .post 去取得不同的值顯示. servers 的狀態.

 

iPhone 開發筆記 – Icons 篇

08 Jan

當我一開始開發 iPhone 時, 對於 icons 大小完全沒概念. 我本身也比較懶得去讀 iPhone SDK, 所以一路走來都是這樣誤打誤撞. 下列是我整理出來的小筆記. 也讓有興趣開發iPhone程式的入門者有一些概念.

上傳到 App Store 的 Icon 要準備的大小如下 :

512×512(實際會縮小到 175×175 放在 app store 上)

舊版 iPhone (3G/3GS) Icon 如下 :

57×57

iPad icon 如下 :

72×72

iPhone 4 或 retina icon 如下 :

114×114

以上 icons 準備好之後, 在你的 xxxx-Info.plist 檔案加入 Icons 的內容, 分別描述不同大小的檔案名稱

這樣你的程式就可以支援 iPhone / iPad 還有 retina 螢幕了

 

[php] plurk bot 跨年撲

31 Dec

先前看到 皮樂的撲. 有人傳說會加業障100. 所以來玩看看吧

材料 :
Linux base機器一台(mac也許可以), at, php 還有 php plurk api,

烹煮方式 :
1. 先確認你的 linux 環境有沒有 at 和 php 指令.
2. 下載 php plurk api , 放到你想執行的目錄.
3. 到 Get an API key 申請 plurk api key.
4. 撰寫簡單的撲機器人, 該檔案放在與 php plurk api 同目錄. 下面是簡單的撲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/php
<?php
 
$api_key = 'YOUR_PLURK_API_KEY';
$username = 'YOUR_PLURK_ID';
$password = 'YOUR_PLURK_PASSWORD';
 
require('plurk_api.php');
 
$plurk = new plurk_api();
$plurk->login($api_key, $username, $password);
 
$output = "新年快樂..林北現在正在拍煙火...";
echo $output;
echo "\n\n ----- add plurk ----- \n";
$plurk->add_plurk('en', 'says', $output);
?>

5. 存檔後用 php 指令去執行它. 理論上它就可以幫你自動撲到你的 plurk. 如下 :

/usr/bin/php /home/sam/plurk/newyear.php

可以把這個指令存到文字檔內. 我命名它為 plurk_newyear

6. 再搭配 at 指令讓他在凌晨的時候撲.

# at 00:00 < plurk_newyear

7. 檢查一下看看它是不是在排程當中.

# at -l
1 2011-01-01 00:00 a sam

順利的話..就會有跨年撲. XD

 
 

註冊 iPhone 多工背景播放音樂

14 Dec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
 
    // Override point for customization after application launch.
    [self.window addSubview:tabBarController.view];
    [self.window makeKeyAndVisible];
 
	UIDevice *thisDevice = [UIDevice currentDevice];
 
	if([thisDevice respondsToSelector:@selector(isMultitaskingSupported)]
	   && thisDevice.multitaskingSupported) {
		UIBackgroundTaskIdentifier backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
			/* just fail if this happens. */
			NSLog(@"BackgroundTask Expiration Handler is called");
			[application endBackgroundTask:backgroundTask];
		}];
	}
 
    return YES;
}
 
 

html5 video tag 簡單示範

11 Nov

再說明 html5 video tag 之前要先了解一下哪些瀏覽器有支援html5 tag及播放格式.

紅色代表不支援. 綠色代表支援. 圖表來源 : “When can I use…

目前而言 safari 5 和 ie 不支援 Ogg/Theora/Vorbis 格式. opera 10.6 和 firefox 3.6 不支援 MPEG-4/H.264/AAC 格式. chrome 兩者都支援.

所以對網頁設計者來說多種瀏覽器支援與不支援是很擾民. 如果用以前的觀念去寫的確很麻煩如下 :

1
2
3
4
5
6
7
8
9
<video id="theVideo" src="http://liho.tw/movie_file.ogg"  width="480" height="320" controls="controls">
Your browser does not support the video tag.
</video>
 
<script type="text/javascript">
if (navigator.appVersion.indexOf("Safari") != -1) {
    document.getElementById('theVideo').src="http://liho.tw/movie_file.mov";
}
</script>

上列範例, 只要遇到 瀏覽器有 “Safari” 字眼. 就使用mp4格式播放. 因為 ogg safari 不支援. 不過上面的示範是比較不妥當的示範.

請看一下 html5 比較正規的寫法

1
2
3
4
5
<video width="480" height="320" controls="controls">
    <source src="http://liho.tw/movie_file.ogg" type="video/ogg" />
    <source src="http://liho.tw/movie_file.mov" type="video/mp4" />
Your browser does not support the video tag.
</video>

這樣瀏覽器就會找到適當的檔案播放. 也不用去判斷使用者使用怎樣的瀏覽器. 省了很多瑣碎的時間.

 
 

HOWTO Delete Non-primary Google Calendar Event?

11 Oct

When you created google calendar event, you will get google event id. something like below :

http://www.google.com/calendar/feeds/default/private/full/yyyyy

After you created non-primary google calendar event, you will get event id similar with following :

http://www.google.com/calendar/feeds/liho.tw_xxxxx%40group.calendar.google.com/

private/full/yyyyy

Following is part of Calendar.php which only supports the google default event :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function deleteEventById ($client, $eventId)
{
  $event = getEvent($client, $eventId);
  $event->delete();
}
 
function getEvent($client, $eventId)
{
  $gdataCal = new Zend_Gdata_Calendar($client);
  $query = $gdataCal->newEventQuery();
  $query->setUser('default');
  $query->setVisibility('private');
  $query->setProjection('full');
  $query->setEvent($eventId);
 
  try {
    $eventEntry = $gdataCal->getCalendarEventEntry($query);
    return $eventEntry;
  } catch (Zend_Gdata_App_Exception $e) {
    var_dump($e);
    return null;
  }
}

You need to un-commet the following :

$query->setUser(‘default’);

And add your calendar id to similar below :

$query->setUser(‘liho.tw_xxxxx%40group.calendar.google.com’);

After you modified, you are able to delete non-primary google calendar event. However, above example is not smart enough. You should rewrite the getEvent function to add non-primary google calendar id. like below :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function deleteEventById ($client, $eventId, $calendarid = "default")
{
  $event = getEvent($client, $eventId, $calendarid);
  $event->delete();
}
 
function getEvent($client, $eventId, $calendarid)
{
  $gdataCal = new Zend_Gdata_Calendar($client);
  $query = $gdataCal->newEventQuery();
  $query->setUser($calendarid);
  $query->setVisibility('private');
  $query->setProjection('full');
  $query->setEvent($eventId);
 
  try {
    $eventEntry = $gdataCal->getCalendarEventEntry($query);
    return $eventEntry;
  } catch (Zend_Gdata_App_Exception $e) {
    var_dump($e);
    return null;
  }
}
 
 

Android – 機房溫度監測簡單範例

01 Sep

分享一個簡單的 android 程式範例. 主要用 ImageView 顯示某 URL 的圖片. 這算是我第一隻比較有用處的 Android 程式


將手機連接到電腦. 啟用 debug 模式. 執行之後就可以將程式部屬到 android 手機了. 這比起蘋果的 Xcode 方便許多. iphone 系列手機沒破解的話就不能直接在設備上執行. 真是有點令人討厭.


執行 Temperature 程式結果

以下為 Android 各檔案的內容 :
AndroidManifest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="tw.edu.sinica.tiara.temperature"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Temperature"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
    </application>
    <uses-sdk android:minSdkVersion="5" />
 
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>

在這裡要注意是否加入 <uses-permission android:name=”android.permission.INTERNET”></uses-permission>. 如果沒加入的話.程式不能存取 internet. 這個我搞了好久才想起來要這樣弄.

下面檔案主要在描述 UI 部分
layout/main.xml

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" android:text="@string/title" android:gravity="center" android:textSize="16sp" android:textColor="#FF000000" android:background="#FFFFFFFF"/>
<ImageView android:id="@+id/ImageViewR937" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FFFFFFFF"></ImageView>
</LinearLayout>

下列檔案在描述 strings
values/strings.xml

1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="title">R937</string>
    <string name="app_name">Temperature</string>
</resources>

以下為程式主要的檔案 :
Temperature.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package tw.edu.sinica.tiara.temperature;
 
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
 
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;
 
public class Temperature extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        ImageView imgView = (ImageView)findViewById(R.id.ImageViewR937);
        Drawable drawable = ImageOperations("http://somewhere/monitoring/temp.jpg");
        imgView.setImageDrawable(drawable);
    }
 
    private Drawable ImageOperations(String url) {
		try {
			InputStream is = (InputStream) new URL(url).getContent();
			Drawable d = Drawable.createFromStream(is, "src name");
			return d;
		} catch (MalformedURLException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
 
}

這樣算是勉強能用的程式. 這還需要在改進. 例如, 使用 Timer 定時讀溫度. 然後設定超過多少溫度顯示 Alert. 當然, 要弄個 Setting 介面讓使用者定義 interval & alert temperature. 之後, 在慢慢加入. 暫時先這樣!

 

精省錢 將字串複製到記憶體筆記

02 Aug
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
if ([host isEqualToString:@"mympro_Copy"]) {
    NSString *command = request.URL.path.lastPathComponent;
    if ([command isEqualToString:@"mobileNumber"]) {
        NSString *mobileNumber = [[NSUserDefaults standardUserDefaults] stringForKey:@"mobileNumber"];
        if (mobileNumber.length != 0) {
            [UIPasteboard generalPasteboard].string = mobileNumber;
            [labelStatus setText:@"門號已複製到記憶體..."];
        } else {
            [labelStatus setText:@"尚未設定門號..."];
        }
    }
    if ([command isEqualToString:@"mobilePasswd"]) {
        NSString *mobilePasswd = [[NSUserDefaults standardUserDefaults] stringForKey:@"mobilePasswd"];
        if (mobilePasswd.length != 0) {
            [UIPasteboard generalPasteboard].string = mobilePasswd;
            [labelStatus setText:@"密碼已複製到記憶體..."];
        } else {
            [labelStatus setText:@"尚未設定密碼..."];
        }
    }
    return NO;
}
 
- (IBAction)btnNumberClicked:(id)sender {
	NSString *mobileNumber = [[NSUserDefaults standardUserDefaults] stringForKey:@"mobileNumber"];
 
	if (mobileNumber.length != 0) {
		[UIPasteboard generalPasteboard].string = mobileNumber;
		[labelStatus setText:@"門號已複製到記憶體..."];
	} else {
		[labelStatus setText:@"尚未設定門號..."];
	}
}
 
- (IBAction)btnPasswdClicked:(id)sender {
	NSString *mobilePasswd = [[NSUserDefaults standardUserDefaults] stringForKey:@"mobilePasswd"];
 
	if (mobilePasswd.length != 0) {
		[UIPasteboard generalPasteboard].string = mobilePasswd;
		[labelStatus setText:@"密碼已複製到記憶體..."];
	} else {
		[labelStatus setText:@"尚未設定密碼..."];
	}
}
 
 

php dateDiff 顯示兩個時間差多少天?多少分鐘?

12 Jul

差幾天 function

1
2
3
4
5
6
7
8
function dateDiff($startDate, $endDate) {
    $startArry = getdate(strtotime($startDate));
    $endArry = getdate(strtotime($endDate));
    $start_date = gregoriantojd($startArry["mon"], $startArry["mday"], $startArry["year"]);
    $end_date = gregoriantojd($endArry["mon"], $endArry["mday"], $endArry["year"]);
 
    return round(($end_date - $start_date), 0);
}

差幾分鐘 function

1
2
3
4
5
6
function minDiff($startTime, $endTime) {
    $start = strtotime($startTime);
    $end = strtotime($endTime);
    $timeDiff = $end - $start;
    return floor($timeDiff / 60);
}

差幾天也可以這樣寫 :

1
2
3
4
5
6
function dateDiff($startTime, $endTime) {
    $start = strtotime($startTime);
    $end = strtotime($endTime);
    $timeDiff = $end - $start;
    return floor($timeDiff / (60 * 60 * 24));
}