Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wanjj_1210
ant-design
提交
765ce7bb
A
ant-design
项目概览
wanjj_1210
/
ant-design
与 Fork 源项目一致
从无法访问的项目Fork
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
ant-design
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
765ce7bb
编写于
12月 21, 2015
作者:
dqaria
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
change api
上级
0e82e140
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
274 addition
and
222 deletion
+274
-222
components/transfer/demo/advanced.md
components/transfer/demo/advanced.md
+33
-8
components/transfer/demo/basic.md
components/transfer/demo/basic.md
+29
-7
components/transfer/demo/search.md
components/transfer/demo/search.md
+53
-2
components/transfer/index.jsx
components/transfer/index.jsx
+87
-157
components/transfer/index.md
components/transfer/index.md
+9
-6
components/transfer/list.jsx
components/transfer/list.jsx
+45
-34
components/transfer/operation.jsx
components/transfer/operation.jsx
+5
-2
components/transfer/search.jsx
components/transfer/search.jsx
+4
-2
style/components/transfer.less
style/components/transfer.less
+9
-4
未找到文件。
components/transfer/demo/advanced.md
浏览文件 @
765ce7bb
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
-
order: 2
-
order: 2
高级用法
穿梭框
高级用法
---
---
...
@@ -13,7 +13,8 @@ const container = document.getElementById('components-transfer-demo-advanced');
...
@@ -13,7 +13,8 @@ const container = document.getElementById('components-transfer-demo-advanced');
const
App
=
React
.
createClass
({
const
App
=
React
.
createClass
({
getInitialState
()
{
getInitialState
()
{
return
{
return
{
mockData
:
[]
mockData
:
[],
targetKeys
:
[],
};
};
},
},
...
@@ -22,23 +23,47 @@ const App = React.createClass({
...
@@ -22,23 +23,47 @@ const App = React.createClass({
},
},
getMock
()
{
getMock
()
{
let
targetKeys
=
[];
let
mockData
=
[];
let
mockData
=
[];
for
(
let
i
=
0
;
i
<
20
;
i
++
)
{
for
(
let
i
=
0
;
i
<
20
;
i
++
)
{
mockData
.
push
({
const
data
=
{
key
:
i
,
title
:
'
内容
'
+
(
i
+
1
),
title
:
'
内容
'
+
(
i
+
1
),
value
:
(
i
+
1
),
description
:
'
内容
'
+
(
i
+
1
)
+
'
的描述
'
,
description
:
'
内容
'
+
(
i
+
1
)
+
'
的描述
'
,
chosen
:
Math
.
random
()
*
2
>
1
chosen
:
Math
.
random
()
*
2
>
1
});
};
if
(
data
.
chosen
)
{
targetKeys
.
push
(
data
.
key
);
}
mockData
.
push
(
data
);
}
}
this
.
setState
({
this
.
setState
({
mockData
:
mockData
mockData
:
mockData
,
targetKeys
:
targetKeys
,
});
});
},
},
handleChange
(
targetKeys
)
{
this
.
setState
({
targetKeys
:
targetKeys
,
});
},
renderFooter
(
props
)
{
return
<
Button
type
=
"primary"
size
=
"small"
style
=
{
{
float
:
'
right
'
,
margin
:
'
5
'
}
}
onClick
=
{
this
.
getMock
}
>
刷新
</
Button
>;
},
render
()
{
render
()
{
return
<
div
>
return
<
div
>
<
Transfer
defaultDataSource
=
{
this
.
state
.
mockData
}
/>
<
Transfer
<
Button
onClick
=
{
this
.
getMock
}
>
刷新数据
</
Button
>
dataSource
=
{
this
.
state
.
mockData
}
showSearch
operations
=
{
[
'
hello
'
,
'
world
'
]
}
targetKeys
=
{
this
.
state
.
targetKeys
}
onChange
=
{
this
.
handleChange
}
render
=
{
(
item
)
=>
{
return
item
.
title
+
item
.
description
;
}
}
footer
=
{
this
.
renderFooter
}
/>
</
div
>;
</
div
>;
}
}
});
});
...
...
components/transfer/demo/basic.md
浏览文件 @
765ce7bb
...
@@ -13,7 +13,8 @@ const container = document.getElementById('components-transfer-demo-basic');
...
@@ -13,7 +13,8 @@ const container = document.getElementById('components-transfer-demo-basic');
const
App
=
React
.
createClass
({
const
App
=
React
.
createClass
({
getInitialState
()
{
getInitialState
()
{
return
{
return
{
mockData
:
[]
mockData
:
[],
targetKeys
:
[],
};
};
},
},
...
@@ -22,23 +23,44 @@ const App = React.createClass({
...
@@ -22,23 +23,44 @@ const App = React.createClass({
},
},
getMock
()
{
getMock
()
{
let
targetKeys
=
[];
let
mockData
=
[];
let
mockData
=
[];
for
(
let
i
=
0
;
i
<
20
;
i
++
)
{
for
(
let
i
=
0
;
i
<
20
;
i
++
)
{
mockData
.
push
({
const
data
=
{
key
:
i
,
title
:
'
内容
'
+
(
i
+
1
),
title
:
'
内容
'
+
(
i
+
1
),
value
:
(
i
+
1
),
description
:
'
内容
'
+
(
i
+
1
)
+
'
的描述
'
,
description
:
'
内容
'
+
(
i
+
1
)
+
'
的描述
'
,
chosen
:
Math
.
random
()
*
2
>
1
chosen
:
Math
.
random
()
*
2
>
1
});
};
if
(
data
.
chosen
)
{
targetKeys
.
push
(
data
.
key
);
}
mockData
.
push
(
data
);
}
}
this
.
setState
({
this
.
setState
({
mockData
:
mockData
mockData
:
mockData
,
targetKeys
:
targetKeys
,
});
});
},
},
handleChange
(
targetKeys
)
{
this
.
setState
({
targetKeys
:
targetKeys
,
});
},
renderFooter
(
props
)
{
return
<
Button
type
=
"primary"
size
=
"small"
style
=
{
{
float
:
'
right
'
,
margin
:
'
5
'
}
}
onClick
=
{
this
.
getMock
}
>
刷新
</
Button
>;
},
render
()
{
render
()
{
return
<
div
>
return
<
div
>
<
Transfer
dataSource
=
{
this
.
state
.
mockData
}
/>
<
Transfer
<
Button
onClick
=
{
this
.
getMock
}
>
刷新数据
</
Button
>
dataSource
=
{
this
.
state
.
mockData
}
targetKeys
=
{
this
.
state
.
targetKeys
}
onChange
=
{
this
.
handleChange
}
render
=
{
(
item
)
=>
{
return
item
.
title
+
item
.
description
;
}
}
/>
</
div
>;
</
div
>;
}
}
});
});
...
...
components/transfer/demo/search.md
浏览文件 @
765ce7bb
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
-
order: 1
-
order: 1
带搜索
的
穿梭框
带搜索
框的
穿梭框
---
---
...
@@ -10,5 +10,56 @@
...
@@ -10,5 +10,56 @@
import
{
Transfer
}
from
'
antd
'
;
import
{
Transfer
}
from
'
antd
'
;
const
container
=
document
.
getElementById
(
'
components-transfer-demo-search
'
);
const
container
=
document
.
getElementById
(
'
components-transfer-demo-search
'
);
ReactDOM
.
render
(<
Transfer
/>,
container
);
const
App
=
React
.
createClass
({
getInitialState
()
{
return
{
mockData
:
[],
targetKeys
:
[],
};
},
componentDidMount
()
{
this
.
getMock
();
},
getMock
()
{
let
targetKeys
=
[];
let
mockData
=
[];
for
(
let
i
=
0
;
i
<
20
;
i
++
)
{
const
data
=
{
key
:
i
,
title
:
'
内容
'
+
(
i
+
1
),
description
:
'
内容
'
+
(
i
+
1
)
+
'
的描述
'
,
chosen
:
Math
.
random
()
*
2
>
1
};
if
(
data
.
chosen
)
{
targetKeys
.
push
(
data
.
key
);
}
mockData
.
push
(
data
);
}
this
.
setState
({
mockData
:
mockData
,
targetKeys
:
targetKeys
,
});
},
handleChange
(
targetKeys
)
{
this
.
setState
({
targetKeys
:
targetKeys
,
});
},
render
()
{
return
<
div
>
<
Transfer
dataSource
=
{
this
.
state
.
mockData
}
showSearch
targetKeys
=
{
this
.
state
.
targetKeys
}
onChange
=
{
this
.
handleChange
}
render
=
{
(
item
)
=>
{
return
item
.
title
+
item
.
description
;}
}
/>
</
div
>;
}
});
ReactDOM
.
render
(<
App
/>,
container
);
````
````
components/transfer/index.jsx
浏览文件 @
765ce7bb
...
@@ -11,194 +11,133 @@ class Transfer extends Component {
...
@@ -11,194 +11,133 @@ class Transfer extends Component {
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
dataSource
:
props
.
dataSource
,
leftFilter
:
''
,
leftFilter
:
''
,
rightFilter
:
''
,
rightFilter
:
''
,
leftCheckedKeys
:
[],
rightCheckedKeys
:
[]
};
};
}
}
componentWillReceiveProps
(
nextProps
)
{
splitDataSource
()
{
this
.
setState
({
const
{
targetKeys
,
dataSource
}
=
this
.
props
;
dataSource
:
nextProps
.
dataSource
,
});
}
checkDirection
(
direction
)
{
let
leftDataSource
=
Object
.
assign
([],
dataSource
);
const
{
filterKey
}
=
this
.
props
;
let
rightDataSource
=
[];
let
{
dataSource
}
=
this
.
state
;
let
result
=
false
;
if
(
direction
===
'
right
'
)
{
if
(
targetKeys
.
length
>
0
)
{
dataSource
.
forEach
((
data
)
=>
{
targetKeys
.
forEach
((
targetKey
)
=>
{
if
(
!
data
[
filterKey
]
&&
data
.
checked
)
{
rightDataSource
.
push
(
leftDataSource
.
find
((
data
,
index
)
=>
{
result
=
true
;
if
(
data
.
key
===
targetKey
)
{
}
leftDataSource
.
splice
(
index
,
1
);
});
return
true
;
}
else
{
}
dataSource
.
forEach
((
data
)
=>
{
}));
if
(
data
[
filterKey
]
&&
data
.
checked
)
{
result
=
true
;
}
});
});
}
}
return
result
;
return
{
leftDataSource
:
leftDataSource
,
rightDataSource
:
rightDataSource
,
};
}
}
moveTo
(
direction
)
{
moveTo
(
direction
)
{
const
{
filterKey
}
=
this
.
props
;
const
{
targetKeys
}
=
this
.
props
;
let
{
dataSource
}
=
this
.
state
;
const
{
leftCheckedKeys
,
rightCheckedKeys
}
=
this
.
state
;
// TODO: 验证是否可点
// move items to target box
if
(
direction
===
'
right
'
)
{
const
newTargetKeys
=
direction
===
'
right
'
?
dataSource
.
forEach
((
data
)
=>
{
leftCheckedKeys
.
concat
(
targetKeys
)
:
// 左边向右移动
targetKeys
.
filter
((
targetKey
)
=>
!
rightCheckedKeys
.
some
((
checkedKey
)
=>
targetKey
===
checkedKey
));
if
(
!
data
[
filterKey
]
&&
data
.
checked
)
{
data
[
filterKey
]
=
true
;
// empty checked keys
data
.
checked
=
false
;
this
.
setState
({
}
[
direction
===
'
right
'
?
'
leftCheckedKeys
'
:
'
rightCheckedKeys
'
]:
[],
});
});
this
.
setState
({
leftFilter
:
''
,
this
.
props
.
onChange
(
newTargetKeys
);
dataSource
:
dataSource
,
});
}
else
{
dataSource
.
forEach
((
data
)
=>
{
if
(
data
[
filterKey
]
&&
data
.
checked
)
{
data
[
filterKey
]
=
false
;
data
.
checked
=
false
;
}
});
this
.
setState
({
rightFilter
:
''
,
dataSource
:
dataSource
,
});
}
}
}
handleSelectAll
(
direction
,
globalCheckStatus
)
{
handleSelectAll
(
direction
,
globalCheckStatus
)
{
const
{
filterKey
}
=
this
.
props
;
const
{
leftDataSource
,
rightDataSource
}
=
this
.
splitDataSource
();
const
{
dataSource
,
leftFilter
,
rightFilter
}
=
this
.
state
;
const
dataSource
=
direction
===
'
left
'
?
leftDataSource
:
rightDataSource
;
switch
(
globalCheckStatus
)
{
let
holder
=
[];
// 选中部分,则全选
case
'
part
'
:
if
(
globalCheckStatus
===
'
all
'
)
{
case
'
none
'
:
holder
=
[];
dataSource
.
forEach
((
data
)
=>
{
}
else
{
// data[filterKey] true 时,在右侧
holder
=
dataSource
.
map
((
data
)
=>
data
.
key
);
if
(
direction
===
'
right
'
&&
data
[
filterKey
]
&&
this
.
matchFilter
(
data
.
title
,
rightFilter
)
||
direction
===
'
left
'
&&
!
data
[
filterKey
]
&&
this
.
matchFilter
(
data
.
title
,
leftFilter
))
{
data
.
checked
=
true
;
}
});
break
;
case
'
all
'
:
dataSource
.
forEach
((
data
)
=>
{
if
(
direction
===
'
right
'
&&
data
[
filterKey
]
&&
this
.
matchFilter
(
data
.
title
,
rightFilter
)
||
direction
===
'
left
'
&&
!
data
[
filterKey
]
&&
this
.
matchFilter
(
data
.
title
,
leftFilter
))
{
data
.
checked
=
false
;
}
});
break
;
default
:
break
;
}
}
this
.
setState
({
this
.
setState
({
dataSource
:
dataSource
,
[
direction
===
'
left
'
?
'
leftCheckedKeys
'
:
'
rightCheckedKeys
'
]:
holder
,
});
});
}
}
handleFilter
(
direction
,
e
)
{
handleFilter
(
direction
,
e
)
{
const
filterText
=
e
.
target
.
value
;
this
.
setState
({
if
(
direction
===
'
left
'
)
{
[
direction
===
'
left
'
?
'
leftFilter
'
:
'
rightFilter
'
]:
e
.
target
.
value
,
this
.
setState
({
});
'
leftFilter
'
:
filterText
,
});
}
else
{
this
.
setState
({
'
rightFilter
'
:
filterText
,
});
}
}
}
handleClear
(
direction
)
{
handleClear
(
direction
)
{
if
(
direction
===
'
left
'
)
{
this
.
setState
({
this
.
setState
({
[
direction
===
'
left
'
?
'
leftFilter
'
:
'
rightFilter
'
]:
''
,
'
leftFilter
'
:
''
,
});
}
else
{
this
.
setState
({
'
rightFilter
'
:
''
,
});
}
}
matchFilter
(
text
,
filterText
)
{
const
regex
=
new
RegExp
(
filterText
);
return
text
.
match
(
regex
);
}
handleSelect
(
selectedItem
,
checked
)
{
const
{
dataSource
}
=
this
.
state
;
dataSource
.
forEach
((
data
)
=>
{
if
(
data
.
value
===
selectedItem
.
value
)
{
data
.
checked
=
checked
;
}
});
});
}
handleSelect
(
direction
,
selectedItem
,
checked
)
{
const
{
leftCheckedKeys
,
rightCheckedKeys
}
=
this
.
state
;
const
holder
=
direction
===
'
left
'
?
leftCheckedKeys
:
rightCheckedKeys
;
const
index
=
holder
.
findIndex
((
key
)
=>
key
===
selectedItem
.
key
);
if
(
index
>
-
1
)
{
holder
.
splice
(
index
,
1
);
}
if
(
checked
)
{
holder
.
push
(
selectedItem
.
key
);
}
this
.
setState
({
this
.
setState
({
dataSource
:
dataSource
,
[
direction
===
'
left
'
?
'
leftCheckedKeys
'
:
'
rightCheckedKeys
'
]:
holder
,
});
});
}
}
render
()
{
render
()
{
const
{
prefixCls
,
leftConfig
,
rightConfig
,
filterKey
,
showSearch
,
header
,
body
,
footer
}
=
this
.
props
;
const
{
prefixCls
,
titles
,
operations
,
showSearch
,
searchPlaceholder
,
body
,
footer
}
=
this
.
props
;
const
{
dataSource
,
leftFilter
,
rightFilter
}
=
this
.
state
;
const
{
leftFilter
,
rightFilter
,
leftCheckedKeys
,
rightCheckedKeys
}
=
this
.
state
;
let
leftDataSource
=
[];
let
rightDataSource
=
[];
let
leftActive
=
this
.
checkDirection
(
'
left
'
);
const
{
leftDataSource
,
rightDataSource
}
=
this
.
splitDataSource
();
let
rightActive
=
this
.
checkDirection
(
'
right
'
);
let
leftActive
=
rightCheckedKeys
.
length
>
0
;
let
rightActive
=
leftCheckedKeys
.
length
>
0
;
dataSource
.
map
((
item
)
=>
{
// filter item
if
(
item
[
filterKey
]
)
{
if
(
this
.
matchFilter
(
item
.
title
,
rightFilter
)
)
{
rightDataSource
.
push
(
item
);
}
}
else
{
if
(
this
.
matchFilter
(
item
.
title
,
leftFilter
)
)
{
leftDataSource
.
push
(
item
);
}
}
});
return
<
div
className
=
{
prefixCls
}
>
return
<
div
className
=
{
prefixCls
}
>
<
List
config
=
{
leftConfig
}
<
List
title
=
{
titles
[
0
]
}
dataSource
=
{
leftDataSource
}
dataSource
=
{
leftDataSource
}
filter
=
{
leftFilter
}
filter
=
{
leftFilter
}
checkedKeys
=
{
leftCheckedKeys
}
handleFilter
=
{
this
.
handleFilter
.
bind
(
this
,
'
left
'
)
}
handleFilter
=
{
this
.
handleFilter
.
bind
(
this
,
'
left
'
)
}
handleClear
=
{
this
.
handleClear
.
bind
(
this
,
'
left
'
)
}
handleClear
=
{
this
.
handleClear
.
bind
(
this
,
'
left
'
)
}
handleSelect
=
{
this
.
handleSelect
.
bind
(
this
)
}
handleSelect
=
{
this
.
handleSelect
.
bind
(
this
,
'
left
'
)
}
handleSelectAll
=
{
this
.
handleSelectAll
.
bind
(
this
,
'
left
'
)
}
handleSelectAll
=
{
this
.
handleSelectAll
.
bind
(
this
,
'
left
'
)
}
position
=
"left"
position
=
"left"
render
=
{
this
.
props
.
render
}
showSearch
=
{
showSearch
}
showSearch
=
{
showSearch
}
header
=
{
hea
der
}
searchPlaceholder
=
{
searchPlacehol
der
}
body
=
{
body
}
body
=
{
body
}
footer
=
{
footer
}
footer
=
{
footer
}
/>
/>
<
Operation
rightActive
=
{
rightActive
}
rightArrowText
=
{
leftConfig
.
operationText
}
moveToRight
=
{
this
.
moveTo
.
bind
(
this
,
'
right
'
)
}
<
Operation
rightActive
=
{
rightActive
}
rightArrowText
=
{
operations
[
0
]
}
moveToRight
=
{
this
.
moveTo
.
bind
(
this
,
'
right
'
)
}
leftActive
=
{
leftActive
}
leftArrowText
=
{
rightConfig
.
operationText
}
moveToLeft
=
{
this
.
moveTo
.
bind
(
this
,
'
left
'
)
}
/>
leftActive
=
{
leftActive
}
leftArrowText
=
{
operations
[
1
]
}
moveToLeft
=
{
this
.
moveTo
.
bind
(
this
,
'
left
'
)
}
/>
<
List
config
=
{
rightConfig
}
<
List
title
=
{
titles
[
1
]
}
dataSource
=
{
rightDataSource
}
dataSource
=
{
rightDataSource
}
filter
=
{
rightFilter
}
filter
=
{
rightFilter
}
checkedKeys
=
{
rightCheckedKeys
}
handleFilter
=
{
this
.
handleFilter
.
bind
(
this
,
'
right
'
)
}
handleFilter
=
{
this
.
handleFilter
.
bind
(
this
,
'
right
'
)
}
handleClear
=
{
this
.
handleClear
.
bind
(
this
,
'
right
'
)
}
handleClear
=
{
this
.
handleClear
.
bind
(
this
,
'
right
'
)
}
handleSelect
=
{
this
.
handleSelect
.
bind
(
this
)
}
handleSelect
=
{
this
.
handleSelect
.
bind
(
this
,
'
right
'
)
}
handleSelectAll
=
{
this
.
handleSelectAll
.
bind
(
this
,
'
right
'
)
}
handleSelectAll
=
{
this
.
handleSelectAll
.
bind
(
this
,
'
right
'
)
}
position
=
"right"
position
=
"right"
render
=
{
this
.
props
.
render
}
showSearch
=
{
showSearch
}
showSearch
=
{
showSearch
}
header
=
{
hea
der
}
searchPlaceholder
=
{
searchPlacehol
der
}
body
=
{
body
}
body
=
{
body
}
footer
=
{
footer
}
footer
=
{
footer
}
/>
/>
...
@@ -206,41 +145,32 @@ class Transfer extends Component {
...
@@ -206,41 +145,32 @@ class Transfer extends Component {
}
}
}
}
// onChange-> do operation
// onSelect-> select action row
Transfer
.
defaultProps
=
{
Transfer
.
defaultProps
=
{
prefixCls
:
'
ant-transfer
'
,
prefixCls
:
'
ant-transfer
'
,
dataSource
:
[],
dataSource
:
[],
dataIndex
:
'
title
'
,
render
:
noop
,
filterKey
:
'
chosen
'
,
targetKeys
:
[]
,
onChange
:
noop
,
onChange
:
noop
,
onSelect
:
noop
,
titles
:
[
'
源列表
'
,
'
目的列表
'
],
leftConfig
:
{
operations
:
[],
title
:
'
源列表
'
,
operationText
:
'
审核入库
'
,
},
rightConfig
:
{
title
:
'
目的列表
'
,
operationText
:
'
审核出库
'
,
},
showSearch
:
false
,
showSearch
:
false
,
searchPlaceholder
:
'
请输入搜索内容
'
,
searchPlaceholder
:
'
请输入搜索内容
'
,
header
:
noop
,
footer
:
noop
,
body
:
noop
,
body
:
noop
,
footer
:
noop
,
};
};
Transfer
.
propTypes
=
{
Transfer
.
propTypes
=
{
prefixCls
:
PropTypes
.
string
,
prefixCls
:
PropTypes
.
string
,
dataSource
:
PropTypes
.
array
,
dataSource
:
PropTypes
.
array
,
render
:
PropTypes
.
func
,
targetKeys
:
PropTypes
.
array
,
onChange
:
PropTypes
.
func
,
titles
:
PropTypes
.
array
,
operations
:
PropTypes
.
array
,
showSearch
:
PropTypes
.
bool
,
showSearch
:
PropTypes
.
bool
,
searchPlaceholder
:
PropTypes
.
string
,
searchPlaceholder
:
PropTypes
.
string
,
operationText
:
PropTypes
.
string
,
body
:
PropTypes
.
func
,
leftTitle
:
PropTypes
.
string
,
footer
:
PropTypes
.
func
,
rightTitle
:
PropTypes
.
string
,
onChange
:
PropTypes
.
func
,
extraRender
:
PropTypes
.
func
,
};
};
export
default
Transfer
;
export
default
Transfer
;
components/transfer/index.md
浏览文件 @
765ce7bb
...
@@ -11,15 +11,18 @@
...
@@ -11,15 +11,18 @@
## 何时使用
## 何时使用
-
需要表示开关状态/两种状态之间的切换时;
-
和
`switch`
的区别是,切换
`switch`
会直接触发状态改变,而
`checkbox`
一般用于状态标记,需要和提交操作配合。
## API
## API
###
Checkbox
###
Transfer
| 参数 | 说明 | 类型 | 可选值 |默认值 |
| 参数 | 说明 | 类型 | 可选值 |默认值 |
|-----------|------------------------------------------|------------|-------|--------|
|-----------|------------------------------------------|------------|-------|--------|
| dataSource | 指定当前是否选中 | boolean | | false |
| dataSource | 数据源 | Array | | [] |
| defaultChecked | 初始是否选中 | boolean | | false |
| render | 渲染每行数据 | Function(record) | | false |
| onChange | 变化时回调函数 | Function(e:Event) | | | |
| targetKeys | 显示在右侧框的数据 | Array | | |
| onChange | 变化时回调函数 | Function(e:Event) | | |
| titles | 标题集合,顺序从左至右 | Array | | [] |
| operations | 集合,顺序从左至右 | Array | | [] |
| showSearch | 是否显示搜索框 | Boolean | | false |
| searchPlaceholder | 搜索框的默认值 | String | | |
components/transfer/list.jsx
浏览文件 @
765ce7bb
...
@@ -2,7 +2,6 @@ import React, { Component, PropTypes } from 'react';
...
@@ -2,7 +2,6 @@ import React, { Component, PropTypes } from 'react';
import
Checkbox
from
'
../checkbox
'
;
import
Checkbox
from
'
../checkbox
'
;
import
Search
from
'
./search.jsx
'
;
import
Search
from
'
./search.jsx
'
;
import
{
classSet
}
from
'
rc-util
'
;
import
{
classSet
}
from
'
rc-util
'
;
function
noop
()
{
function
noop
()
{
}
}
...
@@ -13,11 +12,13 @@ class TransferList extends Component {
...
@@ -13,11 +12,13 @@ class TransferList extends Component {
}
}
handleSelectALl
()
{
handleSelectALl
()
{
this
.
props
.
handleSelectAll
(
this
.
getGlobalCheckStatus
());
this
.
props
.
handleSelectAll
(
this
.
getGlobalCheckStatus
()
,
this
.
filter
);
}
}
handleSelect
(
selectedItem
)
{
handleSelect
(
selectedItem
)
{
this
.
props
.
handleSelect
(
selectedItem
,
!
selectedItem
.
checked
);
const
{
checkedKeys
}
=
this
.
props
;
const
result
=
checkedKeys
.
some
((
key
)
=>
key
===
selectedItem
.
key
);
this
.
props
.
handleSelect
(
selectedItem
,
!
result
);
}
}
handleFilter
(
e
)
{
handleFilter
(
e
)
{
...
@@ -29,18 +30,12 @@ class TransferList extends Component {
...
@@ -29,18 +30,12 @@ class TransferList extends Component {
}
}
getGlobalCheckStatus
()
{
getGlobalCheckStatus
()
{
let
{
dataSource
}
=
this
.
props
;
const
{
dataSource
,
checkedKeys
}
=
this
.
props
;
let
globalCheckStatus
;
let
globalCheckStatus
;
let
selectedRowLength
=
0
;
dataSource
.
forEach
((
data
)
=>
{
if
(
data
.
checked
)
{
selectedRowLength
++
;
}
});
if
(
selectedRowL
ength
>
0
)
{
if
(
checkedKeys
.
l
ength
>
0
)
{
if
(
selectedRowL
ength
<
dataSource
.
length
)
{
if
(
checkedKeys
.
l
ength
<
dataSource
.
length
)
{
globalCheckStatus
=
'
part
'
;
globalCheckStatus
=
'
part
'
;
}
else
{
}
else
{
globalCheckStatus
=
'
all
'
;
globalCheckStatus
=
'
all
'
;
...
@@ -72,38 +67,53 @@ class TransferList extends Component {
...
@@ -72,38 +67,53 @@ class TransferList extends Component {
return
(<
span
ref
=
"checkbox"
className
=
{
classSet
(
checkboxCls
)
}
onClick
=
{
this
.
handleSelectALl
.
bind
(
this
)
}
>
{
customEle
}
</
span
>);
return
(<
span
ref
=
"checkbox"
className
=
{
classSet
(
checkboxCls
)
}
onClick
=
{
this
.
handleSelectALl
.
bind
(
this
)
}
>
{
customEle
}
</
span
>);
}
}
matchFilter
(
text
,
filterText
)
{
const
regex
=
new
RegExp
(
filterText
);
return
text
.
match
(
regex
);
}
render
()
{
render
()
{
const
{
prefixCls
,
config
,
header
,
footer
,
dataSource
,
filter
,
body
}
=
this
.
props
;
let
self
=
this
;
const
{
prefixCls
,
dataSource
,
title
,
filter
,
checkedKeys
,
body
,
footer
,
showSearch
}
=
this
.
props
;
let
globalCheckStatus
=
this
.
getGlobalCheckStatus
();
let
globalCheckStatus
=
this
.
getGlobalCheckStatus
();
// Custom Layout
// Custom Layout
const
headerDom
=
header
({...
this
.
props
,
globalCheckStatus
});
const
footerDom
=
footer
({...
this
.
props
,
globalCheckStatus
});
const
footerDom
=
footer
({...
this
.
props
,
globalCheckStatus
});
const
bodyDom
=
body
({...
this
.
props
,
globalCheckStatus
});
const
bodyDom
=
body
({...
this
.
props
,
globalCheckStatus
});
return
(<
div
className
=
{
prefixCls
}
{
...
this
.
props
}
>
return
(<
div
className
=
{
prefixCls
}
{
...
this
.
props
}
>
{
headerDom
?
<
div
className
=
{
`
${
prefixCls
}
-header`
}
>
<
div
className
=
{
`
${
prefixCls
}
-header`
}
>
{
headerDom
}
</
div
>
:
<
div
className
=
{
`
${
prefixCls
}
-header`
}
>
{
this
.
renderCheckbox
({
{
this
.
renderCheckbox
({
prefixCls
:
'
ant-tree
'
,
prefixCls
:
'
ant-tree
'
,
checked
:
globalCheckStatus
===
'
all
'
,
checked
:
globalCheckStatus
===
'
all
'
,
checkPart
:
globalCheckStatus
===
'
part
'
,
checkPart
:
globalCheckStatus
===
'
part
'
,
checkable
:
<
span
className
=
{
`ant-tree-checkbox-inner`
}
></
span
>
checkable
:
<
span
className
=
{
`ant-tree-checkbox-inner`
}
></
span
>
})
}
{
dataSource
.
length
}
条
})
}
{
(
checkedKeys
.
length
>
0
?
checkedKeys
.
length
+
'
/
'
:
''
)
+
dataSource
.
length
}
条
<
span
className
=
{
`
${
prefixCls
}
-header-title`
}
>
{
config
.
title
}
</
span
>
<
span
className
=
{
`
${
prefixCls
}
-header-title`
}
>
{
title
}
</
span
>
</
div
>
}
</
div
>
{
bodyDom
?
bodyDom
:
<
div
className
=
{
`
${
prefixCls
}
-body`
}
>
{
bodyDom
?
bodyDom
:
<
div
className
=
{
`
${
prefixCls
}
-body-search-wrapper`
}
>
<
div
className
=
{
showSearch
?
`
${
prefixCls
}
-body
${
prefixCls
}
-body-with-search`
:
`
${
prefixCls
}
-body`
}
>
{
showSearch
?
<
div
className
=
{
`
${
prefixCls
}
-body-search-wrapper`
}
>
<
Search
className
=
{
`
${
prefixCls
}
-body-search-bar`
}
onChange
=
{
this
.
handleFilter
.
bind
(
this
)
}
handleClear
=
{
this
.
handleClear
.
bind
(
this
)
}
value
=
{
filter
}
/>
<
Search
className
=
{
`
${
prefixCls
}
-body-search-bar`
}
onChange
=
{
this
.
handleFilter
.
bind
(
this
)
}
handleClear
=
{
this
.
handleClear
.
bind
(
this
)
}
value
=
{
filter
}
/>
</
div
>
</
div
>
:
null
}
<
ul
className
=
""
>
<
ul
>
{
dataSource
.
map
((
item
)
=>
{
{
dataSource
.
length
>
0
?
return
<
li
onClick
=
{
this
.
handleSelect
.
bind
(
this
,
item
)
}
>
dataSource
.
map
((
item
)
=>
{
<
Checkbox
checked
=
{
item
.
checked
}
/>
// apply filter
{
item
.
title
}
const
itemText
=
self
.
props
.
render
(
item
);
</
li
>;})
}
const
filterResult
=
self
.
matchFilter
(
itemText
,
filter
);
if
(
filterResult
)
{
return
<
li
onClick
=
{
this
.
handleSelect
.
bind
(
this
,
item
)
}
>
<
Checkbox
checked
=
{
checkedKeys
.
some
((
key
)
=>
key
===
item
.
key
)
}
/>
{
self
.
props
.
render
(
item
)
}
</
li
>;
}
})
:
<
div
className
=
{
`
${
prefixCls
}
-body-not-found`
}
>
Not Found
</
div
>
}
</
ul
>
</
ul
>
</
div
>
}
</
div
>
}
{
footerDom
?
<
div
className
=
{
`
${
prefixCls
}
-footer`
}
>
{
footerDom
?
<
div
className
=
{
`
${
prefixCls
}
-footer`
}
>
...
@@ -116,12 +126,13 @@ class TransferList extends Component {
...
@@ -116,12 +126,13 @@ class TransferList extends Component {
TransferList
.
defaultProps
=
{
TransferList
.
defaultProps
=
{
prefixCls
:
'
ant-transfer-list
'
,
prefixCls
:
'
ant-transfer-list
'
,
dataSource
:
[],
dataSource
:
[],
defaultDataSource
:
[],
showSearch
:
false
,
searchPlaceholder
:
''
,
handleFilter
:
noop
,
handleFilter
:
noop
,
handleSelect
:
noop
,
handleSelect
:
noop
,
onChange
:
noop
,
handleSelectAll
:
noop
,
render
:
noop
,
//advanced
//advanced
header
:
noop
,
footer
:
noop
,
footer
:
noop
,
body
:
noop
,
body
:
noop
,
};
};
...
@@ -129,12 +140,12 @@ TransferList.defaultProps = {
...
@@ -129,12 +140,12 @@ TransferList.defaultProps = {
TransferList
.
propTypes
=
{
TransferList
.
propTypes
=
{
prefixCls
:
PropTypes
.
string
,
prefixCls
:
PropTypes
.
string
,
dataSource
:
PropTypes
.
array
,
dataSource
:
PropTypes
.
array
,
footer
:
PropTypes
.
func
,
searchPlaceholder
:
PropTypes
.
string
,
searchPlaceholder
:
PropTypes
.
string
,
handleFilter
:
PropTypes
.
func
,
handleFilter
:
PropTypes
.
func
,
handleSelect
:
PropTypes
.
func
,
handleSelect
:
PropTypes
.
func
,
handleSelectAll
:
PropTypes
.
func
,
handleSelectAll
:
PropTypes
.
func
,
config
:
PropTypes
.
object
,
body
:
PropTypes
.
func
,
footer
:
PropTypes
.
func
,
};
};
export
default
TransferList
;
export
default
TransferList
;
components/transfer/operation.jsx
浏览文件 @
765ce7bb
import
React
,
{
Component
,
PropTypes
}
from
'
react
'
;
import
React
,
{
Component
,
PropTypes
}
from
'
react
'
;
import
Button
from
'
../button
'
;
import
Button
from
'
../button
'
;
import
Icon
from
'
../icon
'
;
function
noop
()
{
function
noop
()
{
}
}
...
@@ -9,8 +10,10 @@ class TransferOperation extends Component {
...
@@ -9,8 +10,10 @@ class TransferOperation extends Component {
const
{
moveToLeft
,
moveToRight
,
leftArrowText
,
rightArrowText
,
leftActive
,
rightActive
,
prefixCls
}
=
this
.
props
;
const
{
moveToLeft
,
moveToRight
,
leftArrowText
,
rightArrowText
,
leftActive
,
rightActive
,
prefixCls
}
=
this
.
props
;
return
<
div
className
=
{
`
${
prefixCls
}
`
}
>
return
<
div
className
=
{
`
${
prefixCls
}
`
}
>
<
Button
style
=
{
{
'
margin-bottom
'
:
'
4px
'
}
}
disabled
=
{
!
rightActive
?
'
disabled
'
:
false
}
onClick
=
{
moveToRight
}
>
{
rightArrowText
+
'
>
'
}
</
Button
>
{
rightArrowText
?
<
Button
type
=
"primary"
style
=
{
{
'
margin-bottom
'
:
'
4px
'
}
}
disabled
=
{
!
rightActive
?
'
disabled
'
:
false
}
onClick
=
{
moveToRight
}
>
{
rightArrowText
}
<
Icon
type
=
"right"
/></
Button
>
:
<
Button
disabled
=
{
!
leftActive
?
'
disabled
'
:
false
}
onClick
=
{
moveToLeft
}
>
{
'
<
'
+
leftArrowText
}
</
Button
>
<
Button
type
=
"primary"
style
=
{
{
'
margin-bottom
'
:
'
4px
'
}
}
disabled
=
{
!
rightActive
?
'
disabled
'
:
false
}
onClick
=
{
moveToRight
}
><
Icon
type
=
"right"
/></
Button
>
}
{
leftArrowText
?
<
Button
type
=
"primary"
disabled
=
{
!
leftActive
?
'
disabled
'
:
false
}
onClick
=
{
moveToLeft
}
><
Icon
type
=
"left"
/>
{
leftArrowText
}
</
Button
>
:
<
Button
type
=
"primary"
disabled
=
{
!
leftActive
?
'
disabled
'
:
false
}
onClick
=
{
moveToLeft
}
><
Icon
type
=
"left"
/></
Button
>
}
</
div
>;
</
div
>;
}
}
}
}
...
...
components/transfer/search.jsx
浏览文件 @
765ce7bb
...
@@ -15,9 +15,11 @@ class Search extends Component {
...
@@ -15,9 +15,11 @@ class Search extends Component {
render
()
{
render
()
{
const
{
placeholder
,
value
,
prefixCls
}
=
this
.
props
;
const
{
placeholder
,
value
,
prefixCls
}
=
this
.
props
;
return
<
div
>
return
<
div
>
<
input
placeholder
=
{
placeholder
}
className
=
{
prefixCls
+
'
ant-input
'
}
value
=
{
value
}
ref
=
"input"
onChange
=
{
this
.
handleChange
.
bind
(
this
)
}
/>
<
input
placeholder
=
{
placeholder
}
className
=
{
prefixCls
+
'
ant-input
'
}
value
=
{
value
}
ref
=
"input"
onChange
=
{
this
.
handleChange
.
bind
(
this
)
}
/>
{
value
&&
value
.
length
>
0
?
{
value
&&
value
.
length
>
0
?
<
a
href
=
"javascirpt:;"
className
=
{
prefixCls
+
'
-action
'
}
onClick
=
{
this
.
props
.
handleClear
}
><
i
className
=
"anticon anticon-cross-circle"
></
i
></
a
>
<
a
href
=
"javascirpt:;"
className
=
{
prefixCls
+
'
-action
'
}
onClick
=
{
this
.
props
.
handleClear
}
><
i
className
=
"anticon anticon-cross-circle"
></
i
></
a
>
:
<
span
className
=
{
prefixCls
+
'
-action
'
}
><
i
className
=
"anticon anticon-search"
></
i
></
span
>
:
<
span
className
=
{
prefixCls
+
'
-action
'
}
><
i
className
=
"anticon anticon-search"
></
i
></
span
>
}
}
</
div
>;
</
div
>;
...
...
style/components/transfer.less
浏览文件 @
765ce7bb
...
@@ -8,7 +8,6 @@
...
@@ -8,7 +8,6 @@
display: inline-block;
display: inline-block;
border-radius: 6px;
border-radius: 6px;
width: 160px;
width: 160px;
height: 191px;
&-search {
&-search {
&-action {
&-action {
...
@@ -40,7 +39,6 @@
...
@@ -40,7 +39,6 @@
font-size: 12px;
font-size: 12px;
line-height: 1.5;
line-height: 1.5;
position: relative;
position: relative;
padding-top: 30px;
height: 150px;
height: 150px;
&-search-wrapper {
&-search-wrapper {
...
@@ -50,7 +48,12 @@
...
@@ -50,7 +48,12 @@
height: 28px;
height: 28px;
padding: 4px;
padding: 4px;
width: 100%;
width: 100%;
}
&-not-found {
margin-top: 24px;
color: #ccc;
text-align: center;
}
}
ul {
ul {
...
@@ -66,10 +69,12 @@
...
@@ -66,10 +69,12 @@
}
}
}
}
&-body-with-search {
padding-top: 34px;
}
&-footer {
&-footer {
border-top: 1px solid #e9e9e9;
border-top: 1px solid #e9e9e9;
padding: 8px 20px 16px 10px;
text-align: right;
border-radius: 0 0 5px 5px;
border-radius: 0 0 5px 5px;
}
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录