Thread Rating:
  • 554 Vote(s) - 2.76 Average
  • 1
  • 2
  • 3
  • 4
  • 5
レコードの挿入で一番上の行が選択されてしまう
05-24-2013, 08:12 PM,
#1
レコードの挿入で一番上の行が選択されてしまう
レコードの挿入をするために、インデックスをつけて、選択されている行に追加したレコードが表示されるようにソートしています。

しかし、なぜか、レコードの一番上の行が選択されてしまいます。
batch-events? を利用しないと、現在の選択はそのままとなるのですが、
それだと、レコードの追加に時間がかかってしまいます。

現在のレコードの選択状態を変えないままレコードを挿入するには
どうすればよいでしょうか。

Code:
{let rs:RecordSet =
    {RecordSet
        {RecordFields
            {RecordField "index", domain = int},
            {RecordField "First", domain = String},
            {RecordField "Last", domain = String},
            {RecordField "Age", domain = int}
        }
    }
}
{for i:int = 0 to 100 do
    def rd = {RecordData}
    set rd["index"] = i + 1
    {rs.append rd}
}
{def grid =
    {RecordGrid
        sort = "index",
        record-source = rs
    }
}
{value grid}
{CommandButton
    {on Action do
        let insert-index:int = rs.size
        {if grid.current-index > -1 then
            set insert-index = grid.current-index + 1
        }

        def new-r = {RecordData}|| {rs.new-record}
        set new-r["index"] = insert-index

        ||batch-events? を使うと一番上のレコードが選択されてしまう
        {with rs.batch-events? = true do
            ||挿入のために、対象インデックス以降を+1
            {for r in rs do
                {if r["index"] asa int >= insert-index then
                    set r["index"] = r["index"] asa int + 1
                }
            }
        }
        {rs.append new-r}
        
        ||下記コードで、元の選択状態に戻せるが
        ||画面がちらついたり、スクロール位置が変わるのが問題
||++    {after 0s do
||++        {grid.select-record insert-index}
||++        set grid.current-index = insert-index
||++    }
    }
}
05-27-2013, 10:52 AM,
#2
RE: レコードの挿入で一番上の行が選択されてしまう
RecordGridに以下を設定してみてください。
key-spec = RecordSetDisplay.preserve-indices

05-27-2013, 07:32 PM,
#3
RE: レコードの挿入で一番上の行が選択されてしまう
ヘルプを見ると、 「既存のインデックスおよび選択したものを保存する」とありますね。

私の望む振る舞いをしてくれました。

ありがとうございます。



Code:
{curl 8.0 applet}
{curl-file-attributes character-encoding = "utf8"}
{applet manifest = "manifest.mcurl",
    {compiler-directives careful? = true}
}
{let people:RecordSet =
    {RecordSet
        {RecordFields
            {RecordField "index", caption = "No.", domain = int},
            {RecordField "First", domain = String},
            {RecordField "Last", domain = String},
            {RecordField "Age", domain = int}
        }
    }
}

{for i:int = 0 to 10 do
    {people.append {RecordData index = i + 1, Age = i + 1}}
}
{define-class public SortrderGrid {inherits RecordGrid}
  {constructor public {default
                          record-source:#RecordSet = null,
                          ...}
    {construct-super {splice ...}}
    set self.record-source = record-source
  }
  ||グリッドのヘッダークリックでソートしたときには
  ||RecordSet からはこのイベントは発生しないため、
  ||継承したグリッドの sort セッターで無理やり発生させている
  {setter public {sort sort:#RecordSort}:void
    {if-non-null rs = self.record-source then
        {rs.handle-event {RecordsReordered}}
    }
    set super.sort = sort
  }
  {setter public {record-source rs:#RecordSet}:void
    set super.record-source = rs

    {if-non-null rs = self.record-source then
        {rs.add-event-handler
            {on e:RecordsChanged  at rs:RecordSet  do
                {type-switch e
                 case ra:RecordAdded do
                    def insert-index =  self.current-index + 1
                    {with rs.batch-events? = true do
                        {for idx:int = rs.size above 0  do
                            {if insert-index <= idx then
                                {if-non-null select-record =
                                    {rs.select-one
                                        filter = {RecordFilter
                                                     {proc {r:Record}:bool
                                                         {if r["index"] asa int == idx then
                                                             {return true}
                                                          else
                                                             {return false}
                                                         }
                                                     }
                                                 }
                                    } then
                                    set select-record["index"] = idx + 1
                                }
                            }
                        }
                        set ra.record["index"] = insert-index
                        {if-non-null sort = self.sort then
                            set super.sort = {RecordSort.concat sort, {RecordSort.from-string "index"}}
                        }
                    }
                    {return}
                 case ra:RecordModified do
                 case rr:RecordRemoved do
                 case ro:RecordsReordered do
                 case rbc:RecordsBulkChanges do
                 else
                    {return}
                }
                {after 0s do
                    {with
                        self.records.batch-events? = true ,
                        rs.batch-events? = true do
                        {for r key idx:int in self.records do
                            set r["index"] = idx + 1
                        }
                    }
                }
                {return}
            }
        }

        {rs.handle-event {RecordsReordered }}
    }
  }
}

{def grid =
    {SortrderGrid
        ||レコードの選択行が移動してしまう問題の対応
        key-spec = RecordSetDisplay.preserve-indices,
        record-source = people,
        height = 5in,
        width = 5in
    }
}
{CommandButton
    label = "挿入",
    {on Action do
        {if-non-null rs = grid.record-source then
            {rs.append {RecordData}}
        }
    }
}
{CommandButton
    label = "削除",
    {on Action do
        {if-non-null r = grid.current-record then
            {r.delete}
        }
    }
}
{value grid}
10-28-2013, 06:28 PM, (This post was last modified: 10-28-2013, 06:31 PM by umemura.)
#4
RE: レコードの挿入で一番上の行が選択されてしまう
batch-event?=true の状態で最初のレコードを append する際には、
key-spec = RecordSetDisplay.preserve-indices を指定していても、
select-current-record? = true である以上は、
必ず一番上のレコードが選択されてしまう、という認識ですが、この認識はあっていますか?


回避策は、レコードの追加処理の前に select-current-record? をfalse にして、
追加処理の後に イベントのディスパッチをしたうえで、
select-current-record? を true に戻す、という方法がありそうですが、
できれば、dispatch-events を使いたくありません。
これ以外の方法はありませんか?




Code:
{CommandButton
    label = "レコード追加",
    {on Action do
        set rg.select-current-record? = false
        {with rs.batch-events? = true do
            {for i:int = 0 to 10 do
                def new-r = {rs.new-record}
                {rs.append new-r}
            }
        }
        {dispatch-events false}
        set rg.select-current-record? = true
    }
}
09-19-2014, 06:22 PM, (This post was last modified: 09-19-2014, 06:23 PM by umemura.)
#5
RE: レコードの挿入で一番上の行が選択されてしまう
key-spec = RecordSetDisplay.preserve-indices の設定さえしてあれば、
グリッド内のレコードを、いったんクリア(delete-all)して、
新しいレコードをセットするという一連の処理を with RecordSet.batch-events?=true の中で行うことで、
グリッドのスクロール位置や、選択レコードをそのままの状態にしておけますね。

入力画面などで、DBにいったん登録した後、自動で再検索をおこなうことが多いのですが、
スクロール位置や選択レコードがクリアされてしまうと、
さっきまで修正していたレコードがどれかわからなくなってしまうため、
このやり方でなら状態を保持でき、望ましい振る舞いになりました。


Code:
{def rf-ary = {{Array-of RecordField}}}

{for i:int = 1 to 10 do
    {rf-ary.append {RecordField {String i}, nullable? = true}}
}

{def rs = {RecordSet {RecordFields {splice rf-ary}}}}


{def grid = {RecordGrid
                width =5in, height = 3in
                ,key-spec =  RecordSetDisplay.preserve-indices
                , record-source = rs
                ,select-current-record? = true
            }}

{value grid}


{CommandButton
    label = "レコード選択位置が変わらない",
    {on Action do
        {with rs.batch-events? = true do
            {rs.delete-all}
            {for i:int = 1 to 100 do
                def new-r = {rs.new-record}
                {for rf in rs.fields do
                    set new-r[rf.name] = {String i}
                }
                {rs.append new-r}
            }
            {rs.commit}
        }
    }
}


{CommandButton
    label = "レコード選択位置が一番上になる",
    {on Action do
        {rs.delete-all}
        {with rs.batch-events? = true do
            {for i:int = 1 to 100 do
                def new-r = {rs.new-record}
                {for rf in rs.fields do
                    set new-r[rf.name] = {String i}
                }
                {rs.append new-r}
            }
            {rs.commit}
        }
    }
}

Forum Jump:


Users browsing this thread:

MyBB SQL Error

MyBB has experienced an internal SQL error and cannot continue.

SQL Error:
1017 - Can't find file: 'mybb_threadviews' (errno: 2)
Query:
INSERT INTO mybb_threadviews (tid) VALUES('902')