使用jQuery UI选择句子中的一组单词

时间:2018-02-12 05:55:05

标签: javascript jquery json html5 css3

我正在开发一个Annotating工具,我可以根据鼠标点击来标记单词。我正在使用jQuery UI可选择引用他们的官方页面here

我想在左键+ ctrl点击中选择多个单词作为一个组。例如,如果有一句话:'Steve jobs was the CEO of apple'

我想在jQuery selctable的选择事件中选择Steve jobs作为我的选择1,我也希望Apple作为我的选择2,如下图所示。

  • 选择1 - > Steve jobs
  • 选择2 - > apple

enter image description here

我也想构建一个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

感谢。

0 个答案:

没有答案