我正在开发一个Annotating工具,我可以根据鼠标点击来标记单词。我正在使用jQuery UI可选择引用他们的官方页面here。
我想在左键+ ctrl点击中选择多个单词作为一个组。例如,如果有一句话:'Steve jobs was the CEO of apple'
。
我想在jQuery selctable的选择事件中选择Steve jobs
作为我的选择1,我也希望Apple
作为我的选择2,如下图所示。
Steve jobs
apple
我也想构建一个JSON数组,我可以在其中为表中的每个句子定义我的选择:
[
{
"UtteranceNumber": 0,
"tokenizedUtteranceLookup": [
{
"word": "Steve jobs",
"start": 0,
"end": 10,
"wordIndexInSentence": 0
},
{
"word": "apple",
"start": 26,
"end": 31,
"wordIndexInSentence": 12
}
]
}
]
我已经构建了一个包含如下所有单词的查找表,以及表中的句号。
[
{
"UtteranceNumber": 0,
"tokenizedUtteranceLookup": [
{
"word": "Steve",
"start": 0,
"end": 5,
"wordIndexInSentence": 0
},
{
"word": " ",
"start": 5,
"end": 5,
"wordIndexInSentence": 1
},
{
"word": "jobs",
"start": 6,
"end": 10,
"wordIndexInSentence": 2
},
{
"word": " ",
"start": 10,
"end": 10,
"wordIndexInSentence": 3
},
{
"word": "was",
"start": 11,
"end": 14,
"wordIndexInSentence": 4
},
{
"word": " ",
"start": 14,
"end": 14,
"wordIndexInSentence": 5
},
{
"word": "the",
"start": 15,
"end": 18,
"wordIndexInSentence": 6
},
{
"word": " ",
"start": 18,
"end": 18,
"wordIndexInSentence": 7
},
{
"word": "CEO",
"start": 19,
"end": 22,
"wordIndexInSentence": 8
},
{
"word": " ",
"start": 22,
"end": 22,
"wordIndexInSentence": 9
},
{
"word": "of",
"start": 23,
"end": 25,
"wordIndexInSentence": 10
},
{
"word": " ",
"start": 25,
"end": 25,
"wordIndexInSentence": 11
},
{
"word": "apple",
"start": 26,
"end": 31,
"wordIndexInSentence": 12
}
]
}
]
我尝试过以下代码。
$( function ()
{
$( '#btnAddUtterance' ).click( function ()
{
populateUtterance();
} );
var uttIdx = 0;
var tokenizedUtterances = new Array();
function populateUtterance()
{
let userUtterance = $( '#myInput' ).val();
let tokenizedUtterance = tokenizeUtterance( userUtterance, uttIdx );
let markup = `<tr><td><input type='checkbox' name='record'></td><td> ${tokenizedUtterance} </td> <td>${userUtterance}</td></tr>`;
$( "#tblText tbody" ).append( markup );
uttIdx += 1;
$( '#myInput' ).val( '' );
}
$( "#myInput" ).keyup( function ( event )
{
if ( event.keyCode === 13 )
{
populateUtterance();
}
} );
function findSpacesIndex( utterance )
{
let index = 0;
let spacesIndex = [];
while ( ( index = utterance.indexOf( ' ', index + 1 ) ) > 0 )
{
spacesIndex.push( index );
}
return spacesIndex;
}
function createUtteranceLookup( utterance )
{
let lookUpObject = new Array();
utterance.replace( /[\w'-]+|[^\w\s]+/g, ( word, offset ) =>
lookUpObject.push( { word: word, start: offset, end: offset + word.length } ) );
return lookUpObject;
}
function tokenizeUtterance( utterance )
{
let div = `<div id=${uttIdx} class ='tokenizedUtterance'>`;
let spacesIndex = new Array();
spacesIndex = findSpacesIndex( utterance );
let utteranceLookup = new Array();
for ( let i = 0; i < spacesIndex.length; i++ )
{
utteranceLookup.push( { word: " ", start: spacesIndex[i], end: spacesIndex[i] } );
}
let wordsIndex = [];
wordsIndex = createUtteranceLookup( utterance );
Array.prototype.push.apply( utteranceLookup, wordsIndex );
utteranceLookup.sort( function ( obj1, obj2 )
{
return obj1.start - obj2.start;
} );
for ( let i = 0; i < utteranceLookup.length; i++ )
utteranceLookup[i]["wordIndexInSentence"] = i;
$.each( wordsIndex, function ( index, item )
{
let divId = `div${index}`;
let divStart = item.start;
let divEnd = item.end;
let divValue = item.word;
div += `<div style="display:inline-block;margin:5px; border: 1px solid black;" id = "${divId}" data-start=${divStart} data-end= ${divEnd} data-value= "${divValue}"> ${item.word} </div >`;
} );
tokenizedUtterances.push( { UtteranceNumber: uttIdx, tokenizedUtteranceLookup: utteranceLookup } );
div += '</div>';
$( '#testOutput' ).html( '' );
$( '#testOutput' ).html( JSON.stringify( tokenizedUtterances, undefined, 2 ) );
utteranceLookup = new Array();
return div;
}
var selectedWords = [];
$( ".tokenizedUtterance" ).selectable( {
selected: function ( event, ui )
{
updateSelection();
},
unselecting: function ( event, ui )
{
updateSelection();
}
} );
function updateSelection()
{
var elem = $( ".ui-selected" ).map( function ()
{
return this;
} ).get();
console.log( elem );
var text = '';
$( elem ).each( function ()
{
text += this.innerText + ' ';
} );
$( '#select-result' ).html( text );
}
$( document ).on( "click", '#tblText > tbody > tr > td:nth-child(2)', function ( event )
{
//if ctrl key or left click is pressed, select tokenized word
if ( event.ctrlKey || event.which === 1)
{
$( ".tokenizedUtterance" ).selectable({
selected: function (event, ui)
{
console.log( ui.selected.innerText );
},
unselecting: function ( event, ui )
{
console.log( "In here!" );
}
});
}
console.log( "Selected" );
} );
function removeDuplicatesAndSortArray( selectedWords )
{
selectedWords.sort( function ( obj1, obj2 )
{
return obj1.startPos - obj2.startPos;
} );
let set = new Set( selectedWords );
return Array.from( set.values() );
}
// Find and remove selected table rows
$( document ).on( 'click', '#btnDeleteRow', function ( e )
{
$( "#tblText tbody" ).find( 'input[name="record"]' ).each( function ()
{
if ( $( this ).is( ":checked" ) )
{
$( this ).parents( "tr" ).remove();
$( '#testOutput' ).html( '' );
}
} );
} );
} );
.tokenizedUtterance .ui-selecting
{
background: #FFFF99;
}
.tokenizedUtterance .ui-selected
{
background: #FFFF00;
font-family: 'Segoe UI';
font-style: italic
}
<h2>AnnotationView</h2>
<h2>Enter text to annotate</h2>
<input type="text" id="myInput" />
<button id="btnAddUtterance" class="btn btn-info">Add Utterance</button>
<table id="tblText" class="table table-hover">
<thead>
<tr>
<th>Select</th>
<th>Tokenized User Utterance</th>
<th>Original Utterance</th>
</tr>
</thead>
<tbody></tbody>
</table>
<button id='btnDeleteRow' class='btn btn-danger'>Delete Utterance</button>
<span>You've selected:</span> <span id="select-result"></span>.
<hr />
<h1>Output is: </h1> <br />
<pre id="testOutput" style="word-wrap: break-word; white-space: pre-wrap;"></pre>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
以下是我的解决方案fiddle:
感谢。