@@ -158,7 +158,9 @@ define([
158158if ( subsetType == 'loc' || subsetType == 'iloc' || this . state . dataType == 'Series' ) {
159159tag . appendFormatLine ( '<option value="{0}">{1}</option>' , 'indexing' , 'Indexing' ) ;
160160}
161- tag . appendFormatLine ( '<option value="{0}">{1}</option>' , 'slicing' , 'Slicing' ) ;
161+ if ( subsetType == 'subset' || subsetType == 'loc' || subsetType == 'iloc' ) {
162+ tag . appendFormatLine ( '<option value="{0}">{1}</option>' , 'slicing' , 'Slicing' ) ;
163+ }
162164if ( subsetType == 'subset' || subsetType == 'loc' || subsetType == 'query' ) {
163165tag . appendFormatLine ( '<option value="{0}">{1}</option>' , 'condition' , 'Condition' ) ;
164166}
@@ -447,7 +449,7 @@ define([
447449tag . appendLine ( '<div class="vp-td-line">' ) ;
448450tag . appendLine ( this . templateForConditionColumnInput ( colList ) ) ;
449451tag . appendFormatLine ( '<select class="{0} {1}">' , 'vp-select s' , 'vp-oper-list' ) ;
450- var operList = [ '' , '==' , '!=' , 'in ' , 'notin ' , '<' , '<=' , '>' , '>=' ] ;
452+ var operList = [ '' , '==' , '!=' , 'contains ' , 'notcontains ' , '<' , '<=' , '>' , '>=' , 'starts with' , 'ends with '] ;
451453operList . forEach ( oper => {
452454tag . appendFormatLine ( '<option value="{0}">{1}</option>' , oper , oper ) ;
453455} ) ;
@@ -483,25 +485,26 @@ define([
483485// .index
484486tag . appendFormatLine ( '<option data-code="{0}" value="{1}">{2}</option>' , '.index' , '.index' , 'index' ) ;
485487colList . forEach ( col => {
486- tag . appendFormatLine ( '<option data-code="{0}"value ="{1}">{2 }</option>' ,
487- col . code , col . value , col . label ) ;
488+ tag . appendFormatLine ( '<option data-code="{0}"data-dtype ="{1}" value="{2}">{3 }</option>' ,
489+ col . code , col . dtype , col . value , col . label ) ;
488490} ) ;
489491tag . appendLine ( '</select>' ) ;
490492return tag . toString ( ) ;
491493}
492- templateForConditionCondInput ( category ) {
494+ templateForConditionCondInput ( category , dtype = 'object' ) {
493495var vpCondSuggest = new SuggestInput ( ) ;
494496vpCondSuggest . addClass ( 'vp-input m vp-condition' ) ;
495497
496498if ( category && category . length > 0 ) {
497- vpCondSuggest . setPlaceholder ( " Categorical Dtype ") ;
499+ vpCondSuggest . setPlaceholder ( ( dtype == 'object' ? ' Categorical' : dtype ) + " dtype ") ;
498500vpCondSuggest . setSuggestList ( function ( ) { return category ; } ) ;
499501vpCondSuggest . setSelectEvent ( function ( value ) {
500502$ ( this . wrapSelector ( ) ) . val ( value ) ;
501503$ ( this . wrapSelector ( ) ) . trigger ( 'change' ) ;
502504} ) ;
503505vpCondSuggest . setNormalFilter ( false ) ;
504506} else {
507+ vpCondSuggest . setPlaceholder ( dtype == '' ?'Value' :( dtype + " dtype" ) ) ;
505508}
506509return vpCondSuggest . toTagString ( ) ;
507510}
@@ -689,6 +692,7 @@ define([
689692label :x . location + '' ,
690693value :x . location + '' ,
691694code :x . location + '' ,
695+ dtype :'int'
692696} ;
693697} ) ;
694698}
@@ -1012,7 +1016,7 @@ define([
10121016return {
10131017 ...x ,
10141018value :x . label ,
1015- code :x . value
1019+ code :x . value ,
10161020} ;
10171021} ) ;
10181022that . loadColumnList ( colList ) ;
@@ -1331,25 +1335,42 @@ define([
13311335var thisTag = $ ( this ) ;
13321336var varName = that . state . pandasObject ;
13331337var colName = $ ( this ) . find ( 'option:selected' ) . attr ( 'data-code' ) ;
1338+ var colDtype = $ ( this ) . find ( 'option:selected' ) . attr ( 'data-dtype' ) ;
13341339
13351340var condTag = $ ( this ) . closest ( 'td' ) . find ( '.vp-condition' ) ;
13361341
1337- // get result and load column list
1338- vpKernel . getColumnCategory ( varName , colName ) . then ( function ( resultObj ) {
1339- let { result} = resultObj ;
1340- var category = JSON . parse ( result ) ;
1341- if ( category && category . length > 0 ) {
1342- // if it's categorical column, check 'Text' as default
1343- $ ( thisTag ) . closest ( 'td' ) . find ( '.vp-cond-use-text' ) . prop ( 'checked' , true ) ;
1344- } else {
1345- $ ( thisTag ) . closest ( 'td' ) . find ( '.vp-cond-use-text' ) . prop ( 'checked' , false ) ;
1346- }
1342+ if ( colName == '.index' ) {
1343+ // index
1344+ $ ( thisTag ) . closest ( 'td' ) . find ( '.vp-cond-use-text' ) . prop ( 'checked' , false ) ;
13471345$ ( condTag ) . replaceWith ( function ( ) {
1348- return that . templateForConditionCondInput ( category ) ;
1346+ return that . templateForConditionCondInput ( [ ] , '' ) ;
13491347} ) ;
13501348that . generateCode ( ) ;
1351- } ) ;
1352-
1349+ } else {
1350+ // get result and load column list
1351+ vpKernel . getColumnCategory ( varName , colName ) . then ( function ( resultObj ) {
1352+ let { result} = resultObj ;
1353+ try {
1354+ var category = JSON . parse ( result ) ;
1355+ if ( category && category . length > 0 && colDtype == 'object' ) {
1356+ // if it's categorical column and its dtype is object, check 'Text' as default
1357+ $ ( thisTag ) . closest ( 'td' ) . find ( '.vp-cond-use-text' ) . prop ( 'checked' , true ) ;
1358+ } else {
1359+ $ ( thisTag ) . closest ( 'td' ) . find ( '.vp-cond-use-text' ) . prop ( 'checked' , false ) ;
1360+ }
1361+ $ ( condTag ) . replaceWith ( function ( ) {
1362+ return that . templateForConditionCondInput ( category , colDtype ) ;
1363+ } ) ;
1364+ that . generateCode ( ) ;
1365+ } catch {
1366+ $ ( thisTag ) . closest ( 'td' ) . find ( '.vp-cond-use-text' ) . prop ( 'checked' , false ) ;
1367+ $ ( condTag ) . replaceWith ( function ( ) {
1368+ return that . templateForConditionCondInput ( [ ] , colDtype ) ;
1369+ } ) ;
1370+ that . generateCode ( ) ;
1371+ }
1372+ } ) ;
1373+ }
13531374} ) ;
13541375
13551376// use text
@@ -1430,7 +1451,12 @@ define([
14301451rowList . push ( rowValue ) ;
14311452}
14321453}
1433- rowSelection . appendFormat ( '[{0}]' , rowList . toString ( ) ) ;
1454+ if ( rowList . length == 1 ) {
1455+ // to Series when rowList's length is 1.
1456+ rowSelection . appendFormat ( '{0}' , rowList . toString ( ) ) ;
1457+ } else {
1458+ rowSelection . appendFormat ( '[{0}]' , rowList . toString ( ) ) ;
1459+ }
14341460} else {
14351461rowSelection . append ( ':' ) ;
14361462}
@@ -1465,43 +1491,55 @@ define([
14651491rowSelection . append ( '(' ) ;
14661492}
14671493let colValue = colTag . find ( '.vp-col-list' ) . val ( ) ;
1468- if ( colValue && colValue != '' ) {
1469- if ( colValue == '.index' ) {
1470- rowSelection . append ( 'index' ) ;
1471- } else {
1472- rowSelection . appendFormat ( '{0}' , colValue ) ;
1473- }
1494+ if ( colValue && colValue == '.index' ) {
1495+ colValue = 'index' ;
14741496}
1475- oper && rowSelection . appendFormat ( ' {0}' , oper ) ;
1476- if ( cond ) {
1477- // condition value as text
1478- if ( useText ) {
1479- rowSelection . appendFormat ( " '{0}'" , cond ) ;
1480- } else {
1481- rowSelection . appendFormat ( " {0}" , cond ) ;
1482- }
1497+ let condValue = cond ;
1498+ // condition value as text
1499+ if ( cond && useText ) {
1500+ condValue = com_util . formatString ( "'{0}'" , cond ) ;
1501+ }
1502+ if ( oper == 'contains' ) {
1503+ rowSelection . appendFormat ( '{0}.str.contains({1})' , colValue , condValue ) ;
1504+ } else if ( oper == 'not contains' ) {
1505+ rowSelection . appendFormat ( '~{0}.str.contains({1})' , colValue , condValue ) ;
1506+ } else if ( oper == 'starts with' ) {
1507+ rowSelection . appendFormat ( '{0}.str.startswith({1})' , colValue , condValue ) ;
1508+ } else if ( oper == 'ends with' ) {
1509+ rowSelection . appendFormat ( '{0}.str.endswith({1})' , colValue , condValue ) ;
1510+ } else {
1511+ rowSelection . appendFormat ( '{0}{1}{2}' , colValue , oper != '' ?( ' ' + oper ) :'' , condValue != '' ?( ' ' + condValue ) :'' ) ;
14831512}
14841513if ( condList . length > 1 ) {
14851514rowSelection . append ( ')' ) ;
14861515}
14871516} else {
14881517if ( varType == 'DataFrame' ) {
1489- rowSelection . appendFormat ( '({0}' , varName ) ;
1518+ rowSelection . append ( '(' ) ;
1519+
1520+ let colValue = varName ;
14901521if ( colName && colName != '' ) {
14911522if ( colName == '.index' ) {
1492- rowSelection . appendFormat ( '{0}' , colName ) ;
1523+ colValue += colName ;
14931524} else {
1494- rowSelection . appendFormat ( '[{0}]' , colName ) ;
1525+ colValue += com_util . formatString ( '[{0}]' , colName ) ;
14951526}
14961527}
1497- oper && rowSelection . appendFormat ( ' {0}' , oper ) ;
1498- if ( cond ) {
1499- // condition value as text
1500- if ( useText ) {
1501- rowSelection . appendFormat ( " '{0}'" , cond ) ;
1502- } else {
1503- rowSelection . appendFormat ( " {0}" , cond ) ;
1504- }
1528+ let condValue = cond ;
1529+ // condition value as text
1530+ if ( cond && useText ) {
1531+ condValue = com_util . formatString ( "'{0}'" , cond ) ;
1532+ }
1533+ if ( oper == 'contains' ) {
1534+ rowSelection . appendFormat ( '{0}.str.contains({1})' , colValue , condValue ) ;
1535+ } else if ( oper == 'not contains' ) {
1536+ rowSelection . appendFormat ( '~{0}.str.contains({1})' , colValue , condValue ) ;
1537+ } else if ( oper == 'starts with' ) {
1538+ rowSelection . appendFormat ( '{0}.str.startswith({1})' , colValue , condValue ) ;
1539+ } else if ( oper == 'ends with' ) {
1540+ rowSelection . appendFormat ( '{0}.str.endswith({1})' , colValue , condValue ) ;
1541+ } else {
1542+ rowSelection . appendFormat ( '{0}{1}{2}' , colValue , oper != '' ?( ' ' + oper ) :'' , condValue != '' ?( ' ' + condValue ) :'' ) ;
15051543}
15061544rowSelection . append ( ')' ) ;
15071545} else {