hack のためのネタ帳, etc,,,

以下のコードは、主に Moodle 2.9 を対象としています。

JavaScript

小テストの先頭にラベル等を配置し、HTML 編集モードにして以下のようなコードを埋め込んでおくと解答の文字数を表示できる。
<script>
(function(){
  function countChars() {
    if (location.href.match('/mod/quiz/review.php')) {
      [].forEach.call(document.querySelectorAll(".answer"),function(e){
        let d = document.createElement("div");
        d.textContent = "文字数:"+ e.textContent.length;
        e.parentElement.insertBefore(d, e.nextSibling);
      });
    }
  }
  function onDOMContentLoaded(f) {
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', f);
    } else {
      f();
    }
  }
  onDOMContentLoaded(countChars);
})();
</script>

for ScratchPad

「課題モジュール」の「すべての提出を表示/評定する」の画面を CSV 化する。
javascript:(function(){
  function copyToClipboard(s) {
    let t = document.createElement("textarea");
    document.body.appendChild(t);
    t.value = s;
    t.focus();
    t.select();
    setTimeout(()=>t.parentNode.removeChild(t),0);
    return document.execCommand("copy");
  }
  function copyDialog(s) {
    let d = document.createElement("div");
    Object.assign(d.style, {position: "absolute", top: 0, left:0, width: "100%", height: "100%", border: "1px solid red", background: "white", zIndex: Number.MAX_SAFE_INTEGER});
    document.body.insertBefore(d, document.body.firstChild);

    d.appendChild(document.createTextNode("Copy to Clipboard"));

    let t = document.createElement("textarea");
    Object.assign(t.style, {width: "100%", height: "20em"});
    d.appendChild(t);
    t.value = s;
    t.focus();
    t.select();

    let copy = document.createElement("input");
    Object.assign(copy, {type: "button", value: "copy"});
    copy.addEventListener("click", ()=>{copyToClipboard(s);d.parentNode.removeChild(d);});
    d.appendChild(copy);

    let cancel = document.createElement("input");
    Object.assign(cancel, {type: "button", value: "cancel"});
    cancel.addEventListener("click", ()=>d.parentNode.removeChild(d));
    d.appendChild(cancel);
  }

  let rows = document.querySelector(".paging").parentNode.querySelector("table tbody").rows;
  let s = [].map.call(rows, function({cells}){
    let ret = [2,3,7,8].map(i=>cells[i].textContent);
    if (ret[2].match(/([0-9]+).*?([0-9]+).*?([0-9]+).*?([0-9]+):([0-9]+)/)) ret[2] = `${RegExp.$1}/${RegExp.$2}/${RegExp.$3} ${RegExp.$4}:${RegExp.$5}`;
    return ret;
  }).join("\n");
  
  copyDialog(s);
})();
2020-04-30: update
(function(){
  let t = [].map.call(document.querySelectorAll("#users-list li a[target='_blank']"),e=>e.textContent).sort().map((e,i)=>`${i}\t${e}`).join("\n");
  console.log(t);
})();

orig

「自動出欠」活動の「出欠表」タブで出席者の一覧を得る

2020-04-23: 初版

2020-11-30: 出席人数のカウントを追加

2020-12-14: 出席状況数値ラベル、出席登録時刻、備考の追加

(function(){
  var s = 
    [].reduce.call(document.querySelectorAll(".generaltable tbody tr"),(r,e)=>{
      let c2 = e.querySelector(".c2").textContent;
      let radioname = e.querySelector("input").name;
      let time = e.querySelector(".c11").textContent;
      let remarks = e.querySelector("input[name^='remarks']").value;
      let attend = document.querySelector("form[name='takeattend']").elements[radioname].value;
      let reg = /[PLE]/; // PLEXY=出遅早欠未
      let key={P:1,L:2,E:"",X:3,Y:""};
      if (attend.match(reg)) r.push(`${c2}\t${attend}\t${key[attend]}\t${time}\t${remarks}`);
      return r;
    },[]).join("\n");
  console.log(`${s}`);
  console.log(s.split("\n").length);
  return "";
})();
「ナビゲーション」→「現在のコース」→「...」→「参加者」に連番を振る
(function(){
  let i = 1;
  [].forEach.call(document.querySelectorAll("#participants tbody tr td:first-of-type"),e=>e.insertBefore(document.createTextNode(i++), e.firstChild));
})();
小テストの手動採点で文字数を表示する。
(function(){
  let e = document.querySelectorAll(".qtype_essay_response");
  [].forEach.call(e, e=>e.parentNode.appendChild(document.createTextNode(`文字数:${e.textContent.length}`)));
})();
小テストの提出一覧画面で、checkbox の後ろに index を付与して、提出数の確認を容易にします。
[].forEach.call(document.querySelectorAll("#attempts input[type='checkbox']"),(e, i)=>{
  let t = document.createTextNode(i+1);
  e.parentNode.insertBefore(t, e.nextSibling);
});
ワークショップの評価フェーズにて、相互評価の未提出者と未提出数の一覧を得ます。
(function(){
  let never={};
  [].reduce.call(document.querySelectorAll(".grading-report tbody tr"), (r,e)=>{
    let tds = e.querySelectorAll("td");
    if (tds.length == 4) {
      r = tds[0].textContent;
    }
    if (tds[tds.length -1].classList.contains("null")) {
      never[r] = (never[r] ?? 0) + 1;
    }
    return r;
  },null);
  let a = Object.keys(never).map(k=>`${k}\t:\t${never[k]}`);
  console.log(a.join("\n"));
})();

関連

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

フリーエリア

編集にはIDが必要です