Set initial value with wickedpicker (wickedpicker で初期値を設定する)

時間登録フォームのtimepickerを導入したかったのですが、見た目上一番よかったのが「wickedpicker」だったので実装していたのですが、初期値の入れ方がわからない。編集の際に既存で入っていたデータを全て上書きしてjsで設定した初期値だけが反映されてしまい、動的に変更ができなかった。。

結論からいうと、この記事を参考にしたら動きました。
WickecdPickerで複数入力ボックスの移動時ダイアログをhideする – RUGOH

# coffeeScript で書いてます。

  $('.timepicker').each ->
    default_time = $(this).val()
    if default_time is ""
      default_time = "10:00" # 値がなければ設定する

    options = # オプション
      now: $(this).val() # 既存の値をinputのval()から取得し、timepickerの初期値にする
      minutesInterval: 10
      twentyFour: true
      title: "時間"
    $(this).wickedpicker(options)

ここにたどり着くまでに、いくつか調査したので記載します。

v0.4.1 なら初期値設定できるよ、というissueを発見

github.com やってみたけど動かない!><


timepickerのオプションを紹介する

var options = {
 now: "12:35", //hh:mm 24時間形式で記載、初期値は現在時刻(hh:mm、コロンが大文字だと動かない可能性あり)
 twentyFour: false, //24時間表記を有効にする(初期値:false => 12時間表記)
 upArrow: 'wickedpicker__controls__control-up', //上矢印のスタイルを指定する
 downArrow: 'wickedpicker__controls__control-down', //下矢印のスタイルを指定する
 close: 'wickedpicker__close', //閉じるのスタイルを指定する
 hoverState: 'hover-state', //The hover state class to use, for custom CSS
 title: 'Timepicker', // Wickedpickerのタイトル
 showSeconds: false, //秒を表示する(初期値:false)
 secondsInterval: 1, //秒の間隔を変更します。(初期値:1)
 minutesInterval: 1, //分の間隔を変更します。(初期値:1)
 show: null, //Wickedpickerが表示されたときに呼び出される関数
 clearable: false, //フォーム内に時間を「×」で削除するボタンを表示させるか?  };

$('.timepicker').wickedpicker(options);

【GAS】Google スプレッドシートの表からGoogleカレンダーに予定を追加する

Google スプレッドシートからボタンを押すと、Google カレンダーにスケジュールが登録されます。

f:id:meikotan:20190102181109g:plain
Google スプレッドシートの表からGoogleカレンダーに予定を追加する

今回の要件は

  • スプレッドシートに入力したスケジュールを、カレンダーに反映させたい。
  • カレンダーの色を柔軟に変えたい です。

実際のソースコードはこちらです。
add_schedule_to_calendar/code.gs at master · dobby618/add_schedule_to_calendar · GitHub

一番調べたところ、カレンダーのカラーコード。。Googleの公式ドキュメントにも細かい説明がなかったので・・一つ一つ数字を当てはめて色を確認しました。調査結果のカラーコードはこちら!

GOOGLE_CALENDAR_ACCOUNT = "[スケジュールを反映したいGoogleカレンダーのメールアドレス]"

// カレンダースケジュールの背景色
var SCHEDULE_BACKGROUND_COLOR = 0
// 0 : カレンダーの色
// 1 : ラベンダー(薄紫)
// 2 : セージ(水色)
// 3 : ぶどう(紫)
// 4 : フラミンゴ(ピンク)
// 5 : バナナ(黄色)
// 6 : ミカン(オレンジ)
// 7 : ピーコック(ターコイズブルー)
// 8 : グラファイト(グレー)
// 9 : ブルーベリー(青)
// 10: バジル(緑)
// 11: トマト(赤)

// カレンダーのスケジュール(イベント)を作成し、色をセットしています。  
Cal = CalendarApp.getCalendarById(GOOGLE_CALENDAR_ACCOUNT)
var newEvent = Cal.createAllDayEvent(event_title, new Date(event_day));
newEvent.setColor(SCHEDULE_BACKGROUND_COLOR);      

スプレッドシート側に置くボタンは「挿入」→「図形」から適当なものを作成しください。ボタンにはgetsheetスクリプトを割り当ててください。

以上です。

参考

ココナラで受託開発してます。

ITに関して困ってるけど、周りに頼れる人がいない!ってときにお役にたちたいなと思っています。よろしくお願いします。
https://coconala.com/services/620679

余談

今回はGASのソースコードをバージョン管理したいと思って色々探していたところ、ものすごく使いやすいの見つけました。 https://techblog.recruitjobs.net/development/maneged_google-apps-script_by_github

感謝!

Rails Girls in 愛媛 2019年春開催します!

Rails Girls Japan Advent Calendar 2018 8日目の記事

自己紹介

東京生まれ東京育ちですが、今年の1月から愛媛でフリーランスエンジニア(在宅です)をしてます。今月12月でちょうど一年経ちました。海の横に住んでいるので、息抜きに浜辺の方を散歩することもあります(瀬戸内の海は穏やかで気持ちいですよ~)

別記事ですが、この1年での気付きをモロモロ書いたので田舎ライフに興味があれば読んでもらえると嬉しいです。
http://one-person.hatenablog.jp/entry/2018/12/05/153332

Rails Girls in 愛媛

2019年春?に開催します!もう日付決めました!
日付:2019年6月14日~15日

Rails Girls主催したいと思う理由(時系列っぽくなった)

自分が独学挫折組

もともと自分が高校・大学(情報工学)と理系だったにもかかわらず、授業を通してプログラミング面白いな~という気持ちに一切なれず。。でも出来るようにならなきゃ・・!っていう焦りから、独学で勉強してたんですが全然理解できなかったんですよね。初心者向けって書いてある記事もチンプンカンプンだし、「この1冊でWordpressを使ったHP作れます!」な本でコピペサイトは作れても、細かい修正(応用)はどうやってやるんだ?で挫折しまくってました・・。

教えることが好き

教えること自体は昔から好きで、相手が理解したなっていう瞬間とか、自分が相手の理解できる言葉に落とし込めたな!って瞬間に達成感を感じるタイプです。 プログラム書き始めて2年ぐらいしたとき、そろそろ誰かに教える機会も欲しいな~という欲が出来てきて(当時、自分がずっと下っ端だったのもあって)そういう機会がありそうなイベントをめっちゃ探してました。

DjangoGirlsでコーチに。

そんな中見つけたのがDjangoGirls! (まだこの頃は東京に住んでました) ↓↓このイベントに行ったらDjangoGrilsでコーチ足りないって話を聞いて、その場を手を挙げました(今思えば無茶だったな・・^^;)Pythonほとんどやったことなかったし。
PythonフレームワークDjangoの基礎を学ぼう - connpassDjangoGirls2017 コーチ/メンター募集 - connpass

DjangoGirls自体はRailsGirlsとほぼ構成が同じで、初心者がチュートリアルに沿って1日半かけて学べるイベントです。
Girls系イベントのNice!!なところは、プログラミングを勉強する一回の時間が長いところ。 初心者の方って1、2時間は勉強したことあっても、まるまる一日ってなかなか無いんじゃないかなって思ってて、だからこそ「頭爆発しそうだけど、楽しいかも~」とか、「やっぱ仕事にするのは無理そう・・」とか、新しい気づきが多いイベントなんじゃないかなぁと思います。

Rails Girls の存在を知り、来年は絶対コーチ申込むぞ!と決意

DjangoGirlsに参加してる方から「RailsGirls」もあるよ!という朗報を聞き、全国どこでもいいから来年は絶対RailsGirlsに行こうって決めてました!

愛媛でエンジニア勉強会に参加

愛媛でエンジニア勉強会に行って思ったのが、女性エンジニアの活動率の低さ!唯一、HP制作(a-blog cms)の勉強会は、半分ぐらい女性でしたね。
確かに、男性ばかりのイベントに行くの勇気いるだろうな・・って思ったり。そういう現状を見て、愛媛で女性向けイベントやりたいなぁと思うようになりました。

Rails Girls in Tokyo 10th に応募!そしてスタッフに。

来年愛媛で開催したいんです!と言ったら、Rails Girls in Tokyoのスタッフに入れて頂きました。応募者多数の激戦区だったみたいなので、愛媛で開催したい!って言ってホントよかった^^

江森さんと帰りの電車でいろいろ話す

RailsGirls in 東京の帰り、江森さんと帰りの方向が一緒だったのでRailsGirlsについて色々教えてくれました。
RailsGirlsって男性差別の印象を持たれることも多いという話。参加者が女性限定なので「何で男性はダメなの?」って思うのは確かに、そうだよね、って思う。
RailsGirlsの見解としてざっくり言えば、IT業界全体は男女の人数がアンバランスだから、女性がもう少しITに触れる機会を増やして、男女バランスのとれた良い業界にしていきましょう!という想い(Rails girlsの公式見解)個人的には未経験の女性がいきなりエンジニアばっかりの勉強会に行くこと自体ハードル高いだろうな・・と思ってるので、RailsGirlsの見解にも完全同意です。
また、江森さんからRailsGirlsのあとは男女関係ない Ruby のコミュニティに行って活動してほしいってお話を聞いて、RailsGirlsに参加した後のイメージを自分が全然持ててなかったことに気付けたし、自分の中でモロモロ腑に落ちた感じもしました(江森さんに感謝!)

ehime.rbの立ち上げ

そして愛媛にRubyコミュニティがなかったので、11月~「ehime.rb」を始めました。 会場にお金がかかると続かなそうだな。。と思ってたので、愛媛大学の方に教室?を無料で貸して頂いて、ゆる~く開催しております。

来年のRailsGirlsに参加してくれた方が、その後プログラミングを続けやすい環境を作れたらいいな。

あとは開催まで頑張るぞ。

RailsGirls in 愛媛 ちょっとずつ、準備しています!

今後はどんどん「プログラミングを学ぶ」という敷居が低くなっていくと思うのですが、実際に自分の思い描くものをつくるとか、仕事にするってなると勉強が必要です。 だからこそプログラミングを始めるときに、根本の心理にプログラミングって楽しいな、自分で考えてやってみる!作ってみる!って楽しいな~が感じとってもらえる機会を増やしていきたいと思ってます。そしてその一貫の活動としてRailsGirlsを開催する!という行動に繋がってます!!

おまけ

教える仕事に興味がある方は、エンジニアスクールの先生も面白いですよ~。 私は codecampで講師をしているのですが、RailsGirlsのように教科書はあるものの、教え方、どのような話をして、何を深堀りするかなどは先生の裁量に全て任されてます!なので1対1で相手のレベルに合せながら教えるの好きって方は向いてると思います!
また、codecamp先生内でのslackコミュニティがあって「こんな時どう教えてますか?」とか「もっとこういう形にしませんか?」のような、意見交換も活発で勉強になることばかりです。先生方は在宅などで働いてる方が多いのかな?テキストコミュニケーションに慣れてる方が多い印象で、だからチャットだけでもここまでスムーズな会話が出来るんだろうな~と思ったりします。

先生随時募集してると思うので、興味ある方は是非~。

また、最近知った coderDojo も永住場所を決めたら挑戦したいな・・と思ってます!

pages 差し込み印刷 利用方法

Wordpressの個人ブログで書いてた記事(20180518)の転載です。
f:id:meikotan:20180816133225j:plain
Wordで差し込み印刷ができるのは知ってたんですが、最近Macになってpages(Mac版、Wordみたいなもの)でもできると聞いたので試してみました。

1)差し込み印刷用のアプリケーションをダウンロード

AppleScript and Pages: Placeholder Text, Script Tags, and Data Merge

こちらのサイト(AppleScript関連の情報を提供している)から無料の差し込み印刷用のアプリケーション(Pages Data Merge)をダウンロードできます。 英語ですが、使い方のビデオも閲覧できます。

アプリケーションを開く場合は
システム環境設定 > セキュリティー&プライバシー > 一般
で、ダウンロードしたアプリケーションの実行許可を有効にする必要があります。
※公式サイトの動画を見れば、だいたいわかりますが、ハマったとこ含めて手順残します。

2)準備

  1. pagesファイルの差し込みたい部分の文字列全体を選択し、「フォーマット」「詳細」「プレースホルダテキストとして定義」
  2. 右サイドバーの「スタイル・レイアウト・詳細」の「詳細」を選択
  3. スクリプトタグに任意のコードを入力

3)差し込み印刷をする

  1. Pages Data Mergeを開く
  2. 差し込み印刷するpagesファイル、差し込みデータのnumbersファイルを開く
  3. numbersファイル 差し込みデータの列を選択する
  4. Pages Data Merge ①importを選択す。
  5. 表にnumbersの列名が表示されること、「Clear table」の左側の数字がいんぽーとしたいデータ数か確認する(ヘッダ行も行数に含まれるっぽいので、想定データ数+1になるかも)
  6. numbers の列名を1つ選択し、②プルダウンから「準備」で設定したスクリプトタグを選択する
  7. ③「PDF Document」にする
  8. ④格納したフォルダを選択する
  9. ⑥スタート!

f:id:meikotan:20180816133225j:plain

Chromeヘッドレスでスクレイピング Node.jsライブラリpuppeteer使ってみた

仕事の依頼でスクレイピングすることがあってヘッドレスブラウザを使ってみた。

目的

ホテルや病院などの検索WEBサイトから
検索結果の名前、住所、電話番号などCSVで取得する

ヘッドレスブラウザ

以前はPhantomJSが使われたようですが、Chromeのヘッドレスが今年リリースされたようで、実際両方使ってみたけどスピードはChromeの方が早い。

スクレイピングとは

ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと

ウェブスクレイピング - Wikipedia

Node.jsからChromeのヘッドレスを使うためのライブラリ

chromyだとエラーが出てうまくいかなったし、以下の記事見てpuppeteerを使うことにしました。
ヘッドレスブラウザ(Chrome)を使ってSPAをスクレイピングする - Qiita

puppeteerがこれらのライブラリと一線を画すのは、なんと言っても本家ChromeのDevTool開発チームが作成・メンテナンスしている、という点でしょう。

環境

node v.8.9.1
npm 5.5.1
puppeteer

ソース

参考:puppeteer/search.js at main · puppeteer/puppeteer · GitHub

'use strict';

// puppeteer読込み
const puppeteer = require('puppeteer');
// ファイル読み書きライブラリ
const fs = require('fs');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(【URL】);
  // スクレイピングするセレクタ
  await page.waitForSelector('#search_result .content');

  const links = await page.evaluate(() => {
    const anchors = Array.from(document.querySelectorAll('#search_result .content'));
    return anchors.map(anchor => anchor.textContent).map(text => text.trim().replace(/\s+/g, ','));
  });
  fs.writeFileSync( "puppeteer.csv" , links.join('\n') );

  await browser.close();
})();


スクレイピングも始めてて、Node.jsもほとんど未経験ですが結構簡単にできました!すごいね~。

TechPlay 女子部の皆様へ謝罪

今回はTechPlay女子部のアドベンチャーカレンダーに参加させて頂きました!
初!アドベンチャーカレンダー!(*^^)v
TECH PLAY女子部 Advent Calendar 2017 - Qiita

ただ、私の担当は12日だったのに・・ずるずるずるるるうzzz
ここまで引き延ばしてすみませんでした。。しかも内容も予告してたのと違う・・
来年は計画的に頑張りまっす。

windows10 C++ コマンドプロンプトで実行した時に文字色・背景色を変える

環境

やりたいこと

C++のソースにエスケープシーケンスを使って、ansiカラーを出力させる

#include <iostream>
using namespace std;

int main() {
 printf("\033[33m"); /* 文字色黄色 */
 cout << "HELLO" << endl;

 printf("\033[0m"); /* 色の初期化 */
 cout << "HELLO" << endl;
}

エスケープシーケンスでできること、色について

エスケープシーケンスとは、エスケープコードで始まる文字列で
その中で、ANSIエスケープコードを使って色を変える

  • ANSIエスケープコードのフォーマット
ESC[n1;n2;...X
  • ESCの8進、16進変換
¥033 : 8進数で表記
¥x1b : 16進数で表記

参考

実行してもうまくいかない。

上手く読み込まれず、色のコードがそのまま文字列として出力される
f:id:meikotan:20170223122922j:plain

エスケープシーケンスを読み込むために ansicon を使う

windows xp 以下は System32¥config.nt というファイルに設定を追加するだけで
エスケープシーケンスが読み込めてたみたいだけど
windows10には config.nt 設定ファイル自体が存在しない。

ansiconを使う

以下のサイトを参考にしました。

ansiconをインストールする。
  1. アーカイブを展開
  2. 任意の場所にコピー。
Pathを通して、実行コマンドの前に「ansicon」コマンドを追加する。

※参考サイトにあるAutoRunレジストリエントリはよく理解できなかったので、使わない。

Project.exe の実行

ansicon Project

f:id:meikotan:20170223122946j:plain


ほかに出来ること。

printf("¥033[2J"); /* 画面をクリア */
printf("¥033[5;10H"); /* カーソルを移動 */
printf("\033[33m"); /* 文字色を黄色に */
printf("Hello!¥n"); /* メッセージを出力 */

printf("Press [Enter]...¥n"); /* メッセージを出力 */
(void)getchar(); /* キー入力を待つ */
printf("¥033[93m"); /* 文字色を標準に */

phpフォームからスプレッドシートに書込み

Google Apps Script(以下、GAS)を使ってPOSTでデータを受取る

概要

WEBフォームからデータを送信し、スプレッドシートに登録する

  1. フォームからPOSTでGASにデータを送る
  2. GASからスプレッドシートにデータ書込み・メール配信
  3. フォームは送信と同時にiFrameを使って完了画面を表示する


スプレッドシートとGASの作成

スプレッドシートの作成

スプレッドシートを作成したら
一行目に「timestamp」と「<input>のname属性」を記入する。
f:id:meikotan:20160128112141j:plain

GASの作成

スクリプト エディタ画面を開く
「ツール」→「スクリプト エディタ」を選択
f:id:meikotan:20160112220433j:plain

Main Script(コード.gs)
function doPost(e) {
 // スプレッドシート読込
 var ss = SpreadsheetApp.openById(ScriptProperties.getProperty('active'));
 var sheet = ss.getSheetByName("【要変更】シート名");
 var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]; //headder取得
 var last_row = sheet.getLastRow(); //最終行を取得
  
 // スプレッドシートにフォームのデータを挿入
 for(var key in e.parameter){
  for(var i = 0; i < headers.length; i++){
   // 「timestamp」列に時刻を挿入
   if(headers[i] === 'timestamp'){
    sheet.getRange(last_row + 1, i + 1).setValue(new Date())
    break
   }
   if(headers[i] === key){
    // ヘッダーとkeyが一致した時、その列の最終行にデータを挿入
    sheet.getRange(last_row + 1, i + 1).setValue(e.parameter[key])
    break
   } else if(headers.length === i + 1){
    // ヘッダーとkeyが一致しなかった時、そのkeyを新しいヘッダーとして追加しデータを挿入
    var new_column = sheet.getLastColumn() + 1
    sheet.getRange(1, new_column).setValue(key)
    sheet.getRange(last_row + 1, new_column).setValue(e.parameter[key])
   }
  }
 }

 // メールアドレスへ送信
 if(e.parameter.mail){
  send_mail(e.parameter.mail, headers, e.parameter)
 }
  
 //デバック用
 var app = UiApp.createApplication();
 var panel = app.createVerticalPanel();
 for( p in e.parameters){
  panel.add(app.createLabel(p +" "+e.parameters[p]));
 }
 app.add(panel);
 return app; 
}

 //セットアップ用
 function setUp() {
  var scriptProperties = PropertiesService.getScriptProperties();
  scriptProperties.setProperty('active', SpreadsheetApp.getActiveSpreadsheet().getId());
 }

 function send_mail(mail_address, headers, form_data){
  var text_mail = HtmlService.createTemplateFromFile('mail_data')
  text_mail.headers = headers
  text_mail.form_data = form_data
  
  // メール送る際のオプションを設定する
  var options = {}
  options.noReply = true
  options.from = '【要変更】メールアドレス'
  options.name = '【要変更】受信者表示名'

  try{
   // テキストメールとオプションを設定してメールを送信。
   GmailApp.sendEmail(mail_address, '【要変更】メールタイトル',text_mail.evaluate().getContent(), options)
  }catch(e){
   // エラー発生時は管理者メールアドレスにエラー内容を通知する
   MailApp.sendEmail('管理者メールアドレス', '【要変更】メールタイトル', text_mail.evaluate().getContent(), options);
  }
}


メール本文(mail_data.html)

スクリプトエディタでhtmlを新規作成する。
f:id:meikotan:20160112221219j:plain

<?= form_data.name ?> 様

登録ありがとうございます。
Sampleのメールを送信します。


ソースのセットアップ

「実行」→「setUp」を選択し、「承認」を選択
f:id:meikotan:20160128113953j:plain

GASを公開

「公開」→「ウェブ アプリケーションとして導入」を選択
f:id:meikotan:20160128114959j:plain
※公開した後の「現在のウェブ アプリケーションのURL」をメモ( ..)φメモ

フォームの作成

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
 <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta charset="UTF-8" />
  <title>テストフォームだよ</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
 </head>
 <script>
 <!--
  function validateForm(){
   if(document.getElementById("name_input").value==""){
    alert("なんか書いてくださいよ!");
    return false;
   }else{
    document.getElementById("formID").submit();
    document.getElementById("thankyou").style.display="";
    document.getElementById("thankyou").innerHTML="<center>ありがとう</center>";
    document.getElementById("thanks_none").style.display="none";
   }
  }
 -->
 </script>
 <body>
  <div style="display:none;" id="thankyou"></div>
  <iframe src="#" id="fake-target" name="fake-target" style="width:0px; height:0px; border:0px;"></iframe>
  <div id="thanks_none">
   <form id="formID" action="【要変更】現在のウェブ アプリケーションの URL" method="post" target="fake-target">
    ご氏名<input id="name_input" name="name" type="text" style="ime-mode:active"/><br />
    メール<input name="mail" type="text" style="ime-mode:inactive"/>
    <button onClick="javascript:validateForm();">送信</button>
   </form>
  </div>
 </body>
</html>

※nameに入力がないと、ポップアップのアラートがなります。

送信元メールアドレスの設定

送信元メールアドレスをスプレッドシートを作成したアカウントとは
別のメールアドレスを指定する場合はエイリアスの設定を行います。
[gmail][設定] → [アカウント] → [名前:メールアドレスの追加]
※参考
メール エイリアス アドレスの追加と削除 - G Suite 管理者 ヘルプ

スプレッドシートをDBにする利点

  • 登録されたデータを誰でも簡単に見る・消すことが出来るから
  • 登録者数がExcel上で一覧表示しても苦痛じゃない数なら便利だと思う
  • 共有も簡単
  • Excelなのですぐに集計、データ加工ができる(別でプログラムを書く必要がない)


次回挑戦したいこと

Google App Engine for PHPを使ってみたい
→GASとの違いを明確にしたいな。