String.replaceで知らなかった件

User がノート欄にやたら長いリンク先をそのまま張り付けて、SharePointのリストの表示が著しく損なわれるという現象が自分の管理するサイトコレクションで何件か発生している。 ユーザー教育を行ってリンクの説明を別途短文入力してください、というのは簡単だが、だまって従ってくれるような従業員ばかりではない。 そこで長いリンクを見つけたら強制的に短い文字列に置き換えてしまう、という仕掛けをJavaScriptで書いてしまえばよいのだと思いつき、 試してみた。 結果、以下のような関数を記述し、これを描画時に呼び出す形で解決した。

function shortenAnchor(text) {

    if (text===null) {
        return "";
    }
    let testPattern = /(<a.*?href=.+?>)(.*?)(<\/a?>)/g;

    function replacer(match, p1, p2, p3) {
        if((p2.length)>30) {
            p2 = p2.slice(0, 25) + '...';
        }
        return [p1, p2, p3].join('');
    }

    return text.replace(testPattern, replacer);
}

このコードで何をやっているか。 まずtestPatternを正規表現(RegExp)で記述する。 RegExpで a tag elements をグローバルにトラップする。トラップしたエレメントはタグの前の部分、中身のテキスト部分、タグの後ろの部分にグループわけされ、それぞれの文字列は$1,$2,$3として利用可能になる。( a tag element 全体のマッチは$&)。 そして、あとは String.replaceを使ってマジックをおこすわけだが、Implementationを試行錯誤している最中に 二つ目のパラメーターが実は関数でもよいのだ、というのを本日初めて知ったわけで、それを使ってうまく書くことができた。 ここに関数を使うと、以下の引数が この順番で使えるようになる。 まずは TestPatternそのもののマッチ $&, それぞれグループ分けした部分のマッチ $1,$2,$3。 よって match,p1,p2,p3として利用可能にしておく。実はこの後ろにIndexなどのパラメーターも続くのが、今回は必要がないので無視。 
この replacer という関数ではこの中身の文字列$2(p2)の長さが30文字以上あった場合、最初の25文字以下を切り捨て点三つ…を最後に追加するというもの。 この関数自体を二つ目の引数として使う。 Testしてみたら一発で完動したので感動(おやじギャグです)

普通はString.replaceというと

"this is a pen".replace("this","that") //=>"that is a pen"

という簡単な使い方は知っていたし、 最初のパラメーターを正規表現にすれば $& $1 etc., などのパラメーターを使ってかなり柔軟な置き換えなどができることも知っていて使ってはいたのだが、まさか関数まで使えるとは思っていなかった。 これは素晴らしい、と思った次第

TypeScript その2

年末の休暇を利用してtypeScriptの演習を続行中。 現在まで理解できたところをとりあえず列挙。
nodejs が導入されている必要あり。

npm install typescript -g

これで tscコマンドが使えるようになる。

tsc example.ts

そして、これでexample.ts から example.jsがトランスパイルされる。

プロジェクトフォルダー内で

 tsc init

とやると、コンパイラー設定用のtsconfig.jsonが作成され規定値が設定される。例えば、出力のJavaScriptのレベルが

<pre>”target”:”es5″</pre>

などと記述されている。またコードをトランスパイルしたときのエラーの出力設定などもできる。今のところ全く変更の必要のないレベルでトライアル中。

TypeScript は 基本的には JavaScriptのsuper setなのだが、 ’let’, ‘const’, ‘arrow function ()=>’, ‘ … spread operator’,’Template strings’ などes2015の書式が既にサポートされている。 なのでexample.tsではこれらの言語機能を使ってプログラムを書き、tscでトランスパイルすると、これらの表記をまだサポートしていない現行のブラウザでも動くようなJavaScriptに書き換えてくれる。上のConfig例ではes5レベルのコードに置き換わる。 つまりBabelと同じような使い方ができる、。

type safeなので 異なったタイプの変数へのアサインは論外としてもその可能性が生じそうなコードにはエラー表示が鬼のようにでる。例外処理とか、Interface定義を記述して対処すると満足して何も言わなくなってくれるので、バグの可能性のあるコードを書く可能性が低くなる。

TypeScript 入門

TypeScriptのイントロがDev.office.comにあるので眺めてみた。

tsとして以下の例が載っている。

class Student {
    fullName: string;
    constructor( public firstName, public middleInitial, public lastName){
        this.fullName = firstName + " "+ middleInitial + " " + lastName;
    }
}
interface Person {
    firstName: string;
    lastName : string;
}

function greeter(person: Person){
    return "Hello, "+ person.firstName + " " + person.lastName;

}

let user =new Student("Jane","G.","Doe");

document.body.innerHTML=greeter(user);

これをJSにコンパイルするとこうなる(WebStormはプラグインが動いてダイナミックに自動生成する)

var Student = (function () {
    function Student(firstName, middleInitial, lastName) {
        this.firstName = firstName;
        this.middleInitial = middleInitial;
        this.lastName = lastName;
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
    return Student;
}());
function greeter(person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}
var user = new Student("Jane", "G.", "Doe");
document.body.innerHTML = greeter(user);

うむむむむ。JSのほうがパターンに親近感があって読みやすいんですけど。でもそういうことじゃなくてTypeやクラスの定義がしっかりできて、あとあとの管理が楽、ということなんだろうな。

SharePoint Framework

去年の暮れぐらいだったか、MSのお知らせでSharePoint Frameworkという新しい開発環境を使った SharePoint SiteのCustomizationが可能になりました。という連絡があった。  自分がやりたいSPサイトのCustomizationは 基本的にJavaScriptをページに埋め込むJavaScript Injectionという手法だ。 これでクライエントサイドの描画をコントロールするCSRフックとかリストやファイルのアイテムをAjaxで読み書きするREST APIなどを使ってカスタムページを作るという方法で用が足りてしまうので、あまり気にしていなかったのだが、この方法、最近、その進化が目立つModern view  pageでは使えない。 これは開発するのにVisual Studioが必須であるSharePoint Add-Inでも同じ様で、 どうも今の時点でModern Look componentのCustomizationをサポートしているのはSharePoint Frameworkのみのようなのだ。

で、Dev.Office.comのDocumentationを眺めてみると、なんとこれ、 Node.JS上で全部動いているのだ。

NPMで yo,  gulpと @microsoft/generator-sharepoint を導入し Project folderを作って以下を実行

yo @microsoft/sharepoint

これで必要なファイル群がフォルダーにインストールされる。 hello worldのテンプレートになっているので、これでもうnode.js 上のローカルPCで動くSharePointのページを模したWorkbench上での実行が可能(下記コマンドでDefaultブラウザが勝手に立ち上がる)

gulp trust-dev-center

gulp serve

ここまで、SharePointサイトにアクセスする必要すらない。 Step by Stepはdev.office.comに詳しいので割愛 (Build your first SharePoint client-side web part (Hello World part1)

SharePointのサイトでもすでにDevelopper siteが例えば”https://mysite.com/sites/dev”などとして設定されているなら、 ”https://mysite.com/sites/dev/_layouts/workbench.aspx” にアクセスすると、開発中のwebPart のWorkbenchがSharePoint上で作動する。

そしてこのTool Chainによる開発、Visual Studioが必要ない、というか使えない。dev.office.comのお勧めEditorはVS Code. IDEの例としてJetBrainのWebStormがあげられているなどVisual Studioへの依存性が一切ない。(C#もドットnetも使わないなら当たり前というべきか)

ただ、使われているコードが通常のJavaScriptではなく、TypeScriptなのだ。 TypeScriptのコードは実行時にはJavaScriptにばらされるのでそんなに大きなLearning Curveにはならない、と予測はしているのだが、これは学習する必要があるんだろう。

Node.jsは言語というより開発環境のベースとして使われるので、これ自体を学ぶ必要はない。

VSで使っていたNugetだとかMS buildーtoolなどのツールが、下のようにNode.JS上で動くツールにおきかわっているわけで、今わかっている範囲でまとめると

  1. Node.js: Install するだけ、普通のJavaScriptの知識で十分のはず。
  2. NPM :DependencyのUpdateなど、使い方は学んだほうがよさそう。yarnでもいいのかな
  3. yeoman(yo):Install するだけ、学習の必要性はなさそう
  4. gulp: コマンドをいくつか覚えるだけで学習の必要性はなさそう
  5. typescript: 学習の要あり
  6. webpack:@microsoft モジュールを導入したときに含まれている。さわらなくてよい。何本ものファイルを、一本に圧縮する、というような作業をやっているらしい。
  7. VS CodeまたはWebStorm:Dev.office.comはVS Codeを使った用例を挙げているが、自分は従来からつかっているWebStormを使う。

というわけで、なんと開発環境的には、2,3,4,5,6は1のNodeJSが動けば動くのでなんでもよく、VS codeもWebStormもマルチOS環境で動くので 要するに Linux上で開発できてしまうのだ。

というわけで、javaScriptをかじっている人間にはハードルが低そうな予感。 Linux環境でぼちぼちやってみようかな?

constructing long string with Javascript

There is a time you need to construct a string (for instance, to create a html block) in your code.

In the simpliest approach, youcan constract the string variable  like so

var html='<head><body>’+contentVariable+’more stuff’ + ‘</body></head>’;

this becomes very messy quickly once more variables, more nested construction is needed.

I used to keep concatinating the string, like so

var html='<head></body>’;

html +=  contentVariable;

html += ‘ more Stuff’;

html += ‘</body></head>’;

 

 

Then I saw a pattern in the couple of codes from internet;

var h=[‘<head><body’];

h.push(contentVariable);

h.push(‘more Stuff’);

h.push(‘</head></body>’);

var html=h.join(”);

The More concatenation needed, the more convinient the last method becomes. Key is to join the array element with null delimiter.

exploring SharePoint Online

Our office is soon moving to SharePoint online. Currently we are using SP2007 and Microsoft does not support content migration from 2007 to 2013 or SP online. This is good and bad. Good because we can build sites from scratch, bad because there is no easy way to move our contents from SP2007 to SP online. We should be able to copy files and folders from 2007 to online but all the metadata will be lost. lists will be even tougher. we have the third party solution called ShareGate but IT guys are telling us it is faily slow we can not possibly migrate the whole sites (that is in the size of the order of Terabytes.) and would like to selectively use the tool. Document Management is tricky under the SharePoint at best.

UI has been greatly improved. It is now much easier to interact with contents with JavaScript. I am having tremendous fun with technique like CSR (client side rendering) and REST API that can be used with CSR or as a conetnt of CEWP as usual.  Furthermore , attaching JavaScript code to web part is made less painful by the introduction of JsLink option and inclusion of script web part.

It is also good to have started late in the game. Internet is filled with power user tips. (I can use most of the technique meant for SharePoint 2013 with SharePoint online.)

One of my favorite technique called “calculated column” is still possible with much less hassle.  Again CSR can be used for this with literally one line of code.  Even better, I can forego with calculated columns at all and directly manipulate the target columns and show bar graph or traffic signal instead, using CSR’s context override.

Filter/connection of WebParts on the page is now performed on the list and not view. In another word, the filtering column do not need to be a part of the view.  This is tremendous for me. I no longer need to hide a column that is used for my filter because I don’t need to include the column in the view to start with.

EasyTabs that we used and found so useful for SharePoint 2007 does not work as is.  Again somebody has modified it for SharePoint 2013 and it is  working. Christophe seems to have developed another tool package that includes EasyTabs functionality but my inquiry to him went unanswered so I am using this version.

There is another code called Hillibily Tabs which essentially do the same thing as EasyTabs.  This one uses jQuery and jQuery UI (and CSS) to manipulate the tab, so how do I say this..  It’s flashy and probably more maintainable.

Excellent write up on CSR by Andrei Markeev is here be sure to check other articles by him.

This one by Kaptyn is also good

Many CSR examples are on Office Dev Center, uploaded by Muawiyah Shannak.

The above examples contains calculated column like effect witihout using the calculated column.    However, if you insist Calculated columns to be used, here is Christoph’s explanation of how it can be done.

List Roll up

I was first thinking maybe we need to purchase third party package to do this.  It turned out this is doable with home made JavaScript code with REST API. I am able to Roll up the list (read only at this time, because I only feel comfortable with “GET” potion of the API) in my sandbox, using a couple of sub-sites.  I will try and see how scalable this technique is.

Minimum Download Strategy

Sooner or later, people will hit this “MDS” *issues*  where the view changes back to its default look when switching the view,  or code breaks because it can not find jQuery that was supposed to have been loaded.  I am still learning this but found some blog entries very helpful.

  1. Article by Kalmstrom.com talks about what happens with MDS in very short text and also give pointers to how to deal with it
  2. SharePoint 2013 – A Better Pattern for Client Side Rendering Scripts shows a script pattern that can be used for site with or without MDS feature enabled.

However, my observation is that once you introduce your own code to the mix, then SharePoint engine with MDS seems to try render first with MDS way, then try to render again for “foreign” code.  Because of this, some of the pages does load faster with MDS off.  So turning this feature is not as bad as it may sound.

 

Most of the link here are from various blog entries.  Again, it must be much easier now than two years ago to find the information I need.  MSDN also have many documents I can refer to but there coverage is broader (C#, XML ,.aspx and JavaScript code).  As a business side power user, I (can) only use JavaScript and find those individuals’ entries priceless. My appreciation goes to those who spent many nights to figure out and then took a time to write about it!

Hiding SharePoint list column from list view

This article is about a javascript snippet that hides a specific column from a SharePoint list view. If I google this subject, most of the articles found on the Internet is about hiding a specific column from new, display or edit form. Although javascript can do this, you can do the same thing without use of javascript by enabling list content-type as well. See here.

Not many articles talks about hiding columns from the list view though. (This one is an exception)
The link above shows the solution for toggling the particular columns. I only needed to hide a column from the list. But why do I even want to do that when one can simply create a view without that specific column you don’t want to see?
The reason is that I want to show the list based on filtered value from the column in question. I can add the filter webpart that I can connect to the target list, then specify the column to which the filter webpart will be connected to. In another word, for the filter to work, the column need to be a part of the list view (This is no longer the case with SharePoint 2013 or SharePoint online.  See below). Since the column will always show the same value for all displayed items(filtered value) I want to hide this column. If your company allows the use of SharePoint Designer, then you can use the Dataview webpart where you can use the column that is not shown to filter the items list. But Dataview creation and editing requires SPD. I wanted a easier solution, hence this javascript snippet.

if (typeof jQuery === 'undefined') { throw new Error('hide column snippet requires jQuery') }

//This function gets targetTable object and columnindex to hide
//targetTable is a jQuery object with single element.
function doHideColumn(targetTable,col) {
    targetTable.find(".ms-viewheadertr >*[class^='ms-v']").eq(col).hide();
    targetTable.find(" >tbody >tr").each(function(){$(this).find(">td:eq("+col+")").hide();});
}
$(function() {//this hide the colName column from all table in the page
    var    colName="colToHide";
    var    tarray=$("tr.ms-viewheadertr th:contains('"+ colName +"')");
    var    tlength=tarray.length;
    var    colindex;
    for (var i=0; i<tlength; i++) {
        colindex=$(tarray[i])[0].cellIndex;
        doHideColumn($(tarray[i]).closest('.ms-listviewtable'), colindex);
    }
});

 


This code snippet requires jQuery. You can use content editor Web Parts (CEWP) to include this code (don’t forget to wrap the code with script tag.) It works with SP2007 (My office’s current version) I may need to look at the code again when our IT upgrades the server to either 2013 or O365.  *Edit*  On SharePoint 2013 and SharePoint online filter can be applied to any list column regardless of if the target liist view contains the filtered column.  Therefore, solution explained here is unnecessary. *end Edit *
The code above scans the entire page for column headers with “colToHide” name and hide the column. (or columns if there are multiple lists in the page and if they contains the column with same name)
Since this code uses jQuery array object to hold the column information, it wont be difficult to modify the code to accept more than one column names to hide multiple columns from single list. For now, this snippet achieves what I need.

Filter Web parts are nice. For instance, URL query web parts let me create a page that contents are based on the filtered value in url query. For instance,
http://projectpage.aspx?projphase=1
http://projectpage.aspx?projphase=3
both link goes to the same page but the first link will show project phase 1 list items where the next link will show project phase 3 list.

Android 4.2以降(Nexus 7,Samsung Galaxy etc.,)のUSB Debugモードを有効にする方法

ようするにFirst Generation Nexus 7のUSB Debuggingを有効にするにはどうしたらよいのか、という問題。

従来のAndroid Devciceはセッティングに行ってDevelopper Optionsを選び、その中のUSB DebuggingをOnにすれば事足りるのだが、なんとNexus7ではこのDevelopper Options自体が存在しない。

そんな馬鹿な、とググってみたところ、StackOverflowに以下の記述があった。

SettingのAboutを選択し、Build Numberの欄を7回タップする。

Voodooじみているが、これで Developper OptionがSetting Menuに出現する。

4.2のデバイスってみんなそうかしらん。
と思って手持ちのGalaxy S3(firmware 4.4.2)を眺めてみれば、 おんなじじゃん。 知らなかったのは私ばかりなり。
Easter Egg のノリだね。

Python、comprehension を使った一括処理

Pythonには” … for … in”という構文を使った、一括でメンバー要素を処理する機能がある。Comprehensionと呼ばれ、リスト、セット、辞書に使える。
リストの使用例

>>> a_list =list(range(10))
>>> a_list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a_list = [x**2 for x in a_list]  --List comprehension
>>> a_list
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

If を使い、要素のFilteringをしてから処理することもできる。下はリスト中、偶数だけを処理して新しいリストを作成した例。 

>>> a_list = list(range(10))
>>> a_list = [x**2 for x in a_list if (x%2 ==0)]
>>> a_list
[0, 4, 16, 36, 64]

Python Dictionary の キーと値をスワップして新しい辞書を作る。

>>> week_dict={'Mon':'月','Tue':'火','Wed':'水','Thu':'木','Fri':'金','Sat':'土','Sun':'日'}
>>> youbi_dict={value:key for key,value in week_dict.items()}
>>> youbi_dict
{'木': 'Thu', '土': 'Sat', '月': 'Mon', '火': 'Tue', '水': 'Wed', '日': 'Sun', '金': 'Fri'}
>>> week_dict
{'Mon': '月', 'Fri': '金', 'Tue': '火', 'Sat': '土', 'Sun': '日', 'Wed': '水', 'Thu': '木'}
>>> week_dict['Fri']
'金'
>>> youbi_dict['日']
'Sun'

辞書は順番はキープしないのだ。

突然我が家にPICプログラマ(ライター)がやってきた。

近所で立ち寄れる電子部品を扱う店がRadioShack以外はほとんど壊滅状態になった今日この頃、米国で電子工作に使う部品とか工具を入手しようとすると通信販売に頼るのが普通だろう。 ざっとあげてみるだけでも、ICなどの電子部品はDigikey.comかMouser.com 。
この二社は工場で使うような大口注文からホビースト向けにICのばら売りまでこなしてくれるので重宝する。スイッチとかモーターなどはallelectronics.com。あとはAmazonをみれば大体なんでも入手できる感じ。 またHobbyist専用のキットやSMTのセンサー部品などを扱いやすいように小さな配線板にモジュール的に実装した製品などはadafruit.comやSparkfun.comなどが品揃えも豊富かつ対応が早い。 少し時間がかかるのを覚悟すれば中国からSeeedstudioなども使える。

で、やっとこさ本題に入るが、Sparkfun.comでは年に1度か2度の頻度で梱包があいているものとか、傷不良、旧製品などの半端ものの処分をする。 形式としては、縦横15cm、奥行き20cmくらいの箱に雑多な製品や売れ残り品を詰め込み、福袋のようにして(この場合は福箱か) Dumpster Dive と銘打って売り出す。 数量的には100個くらいのようで、インターネットで時間を決めてよーいドンで始めると2分くらいで完売する。

ところでDumpster Diveという言葉だが、 dumpsterというのは路地の裏側などに置いてある大きなゴミ箱のことである。 このゴミ箱を漁ろうとするとよじ登って入り込み、それこそ潜って物色するような感じになる。 乞食や浮浪者だけではなく、大きな食料品店やレストランのdumpsterは普通に食せるものが平気で捨てられている、ということで、Dumpster Diveの愛好者グループも存在する由である。

そんなところからSparkfunのサイトでも何が入っているかわからないよ、ということでDumpster Diveと銘打ったイベントになっている。

今回、クリックしてみたら運よく購入することができた。 $10プラス送料で一体何が送られてくるか楽しみにしていたのだが、 送ってきたものを開けてみれば想像以上の収穫だった。

  1. CanaKit USB PIC Programmer: Microchip純正 PICKIT2 と完全互換の PICマイコン用プログラマ。まともに購入すると販売価格60ドルくらいである。Firmware 更新用のボタンスイッチの上部がとれていたが、マイコンのプログラムには全く支障がないことを手持ちのPIC18F2550で確認。ボタンも手持ちの押しボタンスイッチに半田付け交換し、完全復帰。PICKIT2と違ってICPの他に40ピンのZIFソケットも付いているのでDIPマイコンを直接焼くことができる。
  2. PCduino: Allwinner A10を実装したArduinoとピンコンパチのArmCortex Development board. これまたMotorolaのLapdockに接続し、内臓2GBフラッシュからLubuntuが立ち上がることを確認。 wifi内臓+Arduinoシールド互換のPcduino2が出たので、Sparkfunはpcduinoの扱いをやめ、旧品在庫として処理したらしい。 これもまともに買えば50ドル以上はしそうだ。
  3. FTDI USB シリアル コンバーター: このブレークアウトほしかったんだよね。上のPcduinoにも実装されているDebug用のシリアルピンに接続するにぴったりではないか。 小売価格15ドル
  4. I2C対応室外用ソーナーモジュール X2 : 1個90ドルくらいするはずなのだが、車載用のバックアップウオーニングか自立歩行ロボットでも作りますか?
  5. 車両Diagnostic Kit: 車両のダイアグコネクタに接続して車両情報を読み取るためのモジュール。コネクタケーブル付き。やはり普通に買うと60ドルくらいする。
  6. 電解コンデンサーが山ほど。
  7. コンパレーターIC,A/DコンバーターIC、Opt Interrupter、ギャップセンサーICがそれぞれ一個づつ.
  8. Banana plug端子が半ダースほど
  9. USBのBlueToothドングル一個
  10. Stepper motor のドライバーボード、6枚続きのアレー状態が一枚。これをうまく切り離すことができれば使えそうだが、手持ちのロータリーツールで破損させずに切断できるかな。
  11. 3ピンロータリーエンコーダ

小売価格としては恐らく300ドル以上は行っている。たまたま当たりだったのか、いつもこんなものなのか、こういうセールがあればまたチャレンジしてみたいと思った次第。

一番嬉しかった(困った?)のはPICプログラマである。 前にも書いたがPICマイコン始めてみたいと思っていたのだが専用プログラマが高いので遠慮していた。それが入手できたのでもう言い訳ができなくなってしまったわけだけれど、今、AVRマイコンの学習も佳境に入っているところだ。 週末の日数が足りないよ..