function clearInputAndSave (e) {
      if (!this.lastModified) return
      if (!this.lastModified.isNew) {
        try {
          var obj = this.getStatementAbout(this.lastModified).object
        } catch (e) { return }
      }
      var s = this.lastModifiedStat // when 'isNew' this is set at addNewObject()

      if (this.lastModified.value !== this.lastModified.defaultValue) {
        if (this.lastModified.value === '') {
                // ToDo: remove this
          this.lastModified.value = this.lastModified.defaultValue
          this.clearInputAndSave()
          return
        } else if (this.lastModified.isNew) {
          s = new UI.rdf.Statement(s.subject, s.predicate, kb.literal(this.lastModified.value), s.why)
                // TODO: DEFINE ERROR CALLBACK
          var defaultpropview = this.views.defaults[s.predicate.uri]
          var trCache = UI.utils.ancestor(this.lastModified, 'TR')
          try {
            UI.store.updater.update([], [s], function (uri, success, errorBody) {
              if (!success) {
                UI.log.error('Error occurs while inserting ' + s + '\n\n' + errorBody + '\n')
                        // UI.log.warn("Error occurs while inserting "+s+'\n\n'+errorBody);
                outline.UserInput.deleteTriple(trCache.lastChild, true)
              }
            })
          } catch (e) {
            UI.log.error('Error inserting fact ' + s + ':\n\t' + e + '\n')
            return
          }
          s = kb.add(s.subject, s.predicate, kb.literal(this.lastModified.value), s.why)
        } else {
          if (this.statIsInverse) {
            UI.log.error("Invalid Input: a literal can't be a subject in RDF/XML")
            this.backOut()
            return
          }
          var s1, s2, s3
          switch (obj.termType) {
            case 'Literal':
                        // generate path and nailing from current values

                        // TODO: DEFINE ERROR CALLBACK
              var valueCache = this.lastModified.value
              trCache = UI.utils.ancestor(this.lastModified, 'TR')
              var oldValue = this.lastModified.defaultValue
              s2 = $rdf.st(s.subject, s.predicate, kb.literal(this.lastModified.value), s.why)
              try {
                UI.store.updater.update([s], [s2], function (uri, success, errorBody) {
                  if (success) {
                    obj.value = valueCache
                  } else {
                    UI.log.warn('Error occurs while editing ' + s + '\n\n' + errorBody)
                    trCache.lastChild.textContent = oldValue
                  }
                  trCache.lastChild.className = trCache.lastChild.className.replace(/ pendingedit/g, '')
                })
              } catch (e) {
                UI.log.warn('Error occurs while editing ' + s + ':\n\t' + e)
                return
              }
                        // obj.value=this.lastModified.value;
                        // UserInputFormula.statements.push(s);
              break
            case 'BlankNode': // a request refill with text
              // var newStat
              var textTerm = kb.literal(this.lastModified.value, '')
                        // <Feature about="labelChoice">
              if (s.predicate.termType === 'Collection') { // case: add triple   ????????? Weird - tbl
                var selectedPredicate = s.predicate.elements[0]   //    @@ TBL elements is a list on the predicate??
                if (kb.any(undefined, selectedPredicate, textTerm)) {
                  if (!e) { // keyboard
                    var tdNode = this.lastModified.parentNode
                    e = {}
                    e.pageX = UI.utils.findPos(tdNode)[0]
                    e.pageY = UI.utils.findPos(tdNode)[1] + tdNode.clientHeight
                  }
                  this.showMenu(e, 'DidYouMeanDialog', undefined, {'dialogTerm': kb.any(undefined, selectedPredicate, textTerm), 'bnodeTerm': s.subject})
                } else {
                  s1 = UI.utils.ancestor(UI.utils.ancestor(this.lastModified, 'TR').parentNode, 'TR').AJAR_statement
                  s2 = $rdf.st(s.subject, selectedPredicate, textTerm, s.why)
                  var type = kb.the(s.subject, rdf('type'))
                  s3 = kb.anyStatementMatching(s.subject, rdf('type'), type, s.why)
                  // TODO: DEFINE ERROR CALLBACK
                  // because the table is repainted, so...
                  trCache = UI.utils.ancestor(UI.utils.ancestor(this.lastModified, 'TR'), 'TD').parentNode
                  try {
                    UI.store.updater.update([], [s1, s2, s3], function (uri, success, errorBody) {
                      if (!success) {
                        console.log('Error occurs while editing ' + s1 + '\n\n' + errorBody)
                        outline.UserInput.deleteTriple(trCache.lastChild, true)   // @@@@ This
                      }
                    })
                  } catch (e) {
                    console.log('Error occurs while editing ' + s1 + ':\n\t' + e)
                    return
                  }
                  kb.remove(s)
                  kb.add(s.subject, selectedPredicate, textTerm, s.why) // was: newStat =
                  // a subtle bug occurs here, if foaf:nick hasn't been dereferneced,
                  // this add will cause a repainting
                }
                var enclosingTd = UI.utils.ancestor(this.lastModified.parentNode.parentNode, 'TD')
                const defaultPane = panes.default // @@ check
                outline.outlineExpand(enclosingTd, s.subject, {'pane': defaultPane, 'already': true})
                outline.walk('right', outline.focusTd)
                        // </Feature>
              } else {
                this.fillInRequest('object', this.lastModified.parentNode, kb.literal(this.lastModified.value))
                return // The new Td is already generated by fillInRequest, so it's done.
              }
              break
          }
        }
      } else if (this.lastModified.isNew) { // generate 'Request', there is no way you can input ' (Please Input) '
        var trNode = UI.utils.ancestor(this.lastModified, 'TR')
        var reqTerm = this.generateRequest('(To be determined. Re-type of drag an object onto this field)')
        var preStat = trNode.previousSibling.AJAR_statement // the statement of the same predicate
        this.formUndetStat(trNode, preStat.subject, preStat.predicate, reqTerm, preStat.why, false)
            // this why being the same as the previous statement
        this.lastModified = null

            // UI.log.warn("test .isNew)");
        return
      } else if (s.predicate.termType === 'Collection') {
        kb.removeMany(s.subject)
        var upperTr = UI.utils.ancestor(UI.utils.ancestor(this.lastModified, 'TR').parentNode, 'TR')
        preStat = upperTr.AJAR_statement
        reqTerm = this.generateRequest('(To be determined. Re-type of drag an object onto this field)')
        this.formUndetStat(upperTr, preStat.subject, preStat.predicate, reqTerm, preStat.why, false)
        outline.replaceTD(outline.outlineObjectTD(reqTerm, defaultpropview), upperTr.lastChild)
        this.lastModified = null
        return
      } else
      /*
      if ((s.object.termType === 'BlankNode' && !this.statIsInverse) ||
                  s.subject.termType === 'BlankNode' && this.statIsInverse) {
        this.backOut()
        return
      */
      if (this.statIsInverse) {
        if (s.subject.termType === 'BlankNode') {
          this.backOut()
          return
        }
      } else {
        if (s.object.termType === 'BlankNode') {
          this.backOut()
          return
        }
      }
        // case modified - literal modification only(for now).
      trNode = UI.utils.ancestor(this.lastModified, 'TR')
      // var defaultpropview = this.views.defaults[s.predicate.uri]

      if (!this.statIsInverse) {
            // this is for an old feature
            // outline.replaceTD(outline.outlineObjectTD(s.object, defaultpropview),trNode.lastChild);
        outline.replaceTD(outline.outlineObjectTD(kb.literal(this.lastModified.value), defaultpropview), trNode.lastChild)
      } else {
        outline.replaceTD(outline.outlineObjectTD(s.subject, defaultpropview), trNode.lastChild)
      }
      if (this.lastModified.value !== this.lastModified.defaultValue) { trNode.lastChild.className += ' pendingedit' }
        // trNode.AJAR_statement=s;//you don't have to set AJAR_inverse because it's not changed
        // This is going to be painful when predicate-edit allowed
      this.lastModified = null
    }
function clearInputAndSave (e) {
      if (!this.lastModified) return
      if (!this.lastModified.isNew) {
        try {
          var obj = this.getStatementAbout(this.lastModified).object
        } catch (e) { return }
      }
      var s = this.lastModifiedStat 

      if (this.lastModified.value !== this.lastModified.defaultValue) {
        if (this.lastModified.value === '') {
                
          this.lastModified.value = this.lastModified.defaultValue
          this.clearInputAndSave()
          return
        } else if (this.lastModified.isNew) {
          s = new UI.rdf.Statement(s.subject, s.predicate, kb.literal(this.lastModified.value), s.why)
                
          var defaultpropview = this.views.defaults[s.predicate.uri]
          var trCache = UI.utils.ancestor(this.lastModified, 'TR')
          try {
            UI.store.updater.update([], [s], function (uri, success, errorBody) {
              if (!success) {
                UI.log.error('Error occurs while inserting ' + s + '\n\n' + errorBody + '\n')
                        
                outline.UserInput.deleteTriple(trCache.lastChild, true)
              }
            })
          } catch (e) {
            UI.log.error('Error inserting fact ' + s + ':\n\t' + e + '\n')
            return
          }
          s = kb.add(s.subject, s.predicate, kb.literal(this.lastModified.value), s.why)
        } else {
          if (this.statIsInverse) {
            UI.log.error("Invalid Input: a literal can't be a subject in RDF/XML")
            this.backOut()
            return
          }
          var s1, s2, s3
          switch (obj.termType) {
            case 'Literal':
                        

                        
              var valueCache = this.lastModified.value
              trCache = UI.utils.ancestor(this.lastModified, 'TR')
              var oldValue = this.lastModified.defaultValue
              s2 = $rdf.st(s.subject, s.predicate, kb.literal(this.lastModified.value), s.why)
              try {
                UI.store.updater.update([s], [s2], function (uri, success, errorBody) {
                  if (success) {
                    obj.value = valueCache
                  } else {
                    UI.log.warn('Error occurs while editing ' + s + '\n\n' + errorBody)
                    trCache.lastChild.textContent = oldValue
                  }
                  trCache.lastChild.className = trCache.lastChild.className.replace(/ pendingedit/g, '')
                })
              } catch (e) {
                UI.log.warn('Error occurs while editing ' + s + ':\n\t' + e)
                return
              }
                        
                        
              break
            case 'BlankNode': 
              
              var textTerm = kb.literal(this.lastModified.value, '')
                        
              if (s.predicate.termType === 'Collection') { 
                var selectedPredicate = s.predicate.elements[0]   
                if (kb.any(undefined, selectedPredicate, textTerm)) {
                  if (!e) { 
                    var tdNode = this.lastModified.parentNode
                    e = {}
                    e.pageX = UI.utils.findPos(tdNode)[0]
                    e.pageY = UI.utils.findPos(tdNode)[1] + tdNode.clientHeight
                  }
                  this.showMenu(e, 'DidYouMeanDialog', undefined, {'dialogTerm': kb.any(undefined, selectedPredicate, textTerm), 'bnodeTerm': s.subject})
                } else {
                  s1 = UI.utils.ancestor(UI.utils.ancestor(this.lastModified, 'TR').parentNode, 'TR').AJAR_statement
                  s2 = $rdf.st(s.subject, selectedPredicate, textTerm, s.why)
                  var type = kb.the(s.subject, rdf('type'))
                  s3 = kb.anyStatementMatching(s.subject, rdf('type'), type, s.why)
                  
                  
                  trCache = UI.utils.ancestor(UI.utils.ancestor(this.lastModified, 'TR'), 'TD').parentNode
                  try {
                    UI.store.updater.update([], [s1, s2, s3], function (uri, success, errorBody) {
                      if (!success) {
                        console.log('Error occurs while editing ' + s1 + '\n\n' + errorBody)
                        outline.UserInput.deleteTriple(trCache.lastChild, true)   
                      }
                    })
                  } catch (e) {
                    console.log('Error occurs while editing ' + s1 + ':\n\t' + e)
                    return
                  }
                  kb.remove(s)
                  kb.add(s.subject, selectedPredicate, textTerm, s.why) 
                  
                  
                }
                var enclosingTd = UI.utils.ancestor(this.lastModified.parentNode.parentNode, 'TD')
                const defaultPane = panes.default 
                outline.outlineExpand(enclosingTd, s.subject, {'pane': defaultPane, 'already': true})
                outline.walk('right', outline.focusTd)
                        
              } else {
                this.fillInRequest('object', this.lastModified.parentNode, kb.literal(this.lastModified.value))
                return 
              }
              break
          }
        }
      } else if (this.lastModified.isNew) { 
        var trNode = UI.utils.ancestor(this.lastModified, 'TR')
        var reqTerm = this.generateRequest('(To be determined. Re-type of drag an object onto this field)')
        var preStat = trNode.previousSibling.AJAR_statement 
        this.formUndetStat(trNode, preStat.subject, preStat.predicate, reqTerm, preStat.why, false)
            
        this.lastModified = null

            
        return
      } else if (s.predicate.termType === 'Collection') {
        kb.removeMany(s.subject)
        var upperTr = UI.utils.ancestor(UI.utils.ancestor(this.lastModified, 'TR').parentNode, 'TR')
        preStat = upperTr.AJAR_statement
        reqTerm = this.generateRequest('(To be determined. Re-type of drag an object onto this field)')
        this.formUndetStat(upperTr, preStat.subject, preStat.predicate, reqTerm, preStat.why, false)
        outline.replaceTD(outline.outlineObjectTD(reqTerm, defaultpropview), upperTr.lastChild)
        this.lastModified = null
        return
      } else
      
      if (this.statIsInverse) {
        if (s.subject.termType === 'BlankNode') {
          this.backOut()
          return
        }
      } else {
        if (s.object.termType === 'BlankNode') {
          this.backOut()
          return
        }
      }
        
      trNode = UI.utils.ancestor(this.lastModified, 'TR')
      

      if (!this.statIsInverse) {
            
            
        outline.replaceTD(outline.outlineObjectTD(kb.literal(this.lastModified.value), defaultpropview), trNode.lastChild)
      } else {
        outline.replaceTD(outline.outlineObjectTD(s.subject, defaultpropview), trNode.lastChild)
      }
      if (this.lastModified.value !== this.lastModified.defaultValue) { trNode.lastChild.className += ' pendingedit' }
        
        
      this.lastModified = null
    }
function clearInputAndSave ( e ) { if ( ! this . lastModified ) return if ( ! this . lastModified . isNew ) { try { var obj = this . getStatementAbout ( this . lastModified ) . object } catch ( e ) { return } } var s = this . lastModifiedStat // when 'isNew' this is set at addNewObject() if ( this . lastModified . value !== this . lastModified . defaultValue ) { if ( this . lastModified . value === '' ) { // ToDo: remove this this . lastModified . value = this . lastModified . defaultValue this . clearInputAndSave ( ) return } else if ( this . lastModified . isNew ) { s = new UI . rdf . Statement ( s . subject , s . predicate , kb . literal ( this . lastModified . value ) , s . why ) // TODO: DEFINE ERROR CALLBACK var defaultpropview = this . views . defaults [ s . predicate . uri ] var trCache = UI . utils . ancestor ( this . lastModified , 'TR' ) try { UI . store . updater . update ( [ ] , [ s ] , function ( uri , success , errorBody ) { if ( ! success ) { UI . log . error ( 'Error occurs while inserting ' + s + '\n\n' + errorBody + '\n' ) // UI.log.warn("Error occurs while inserting "+s+'\n\n'+errorBody); outline . UserInput . deleteTriple ( trCache . lastChild , true ) } } ) } catch ( e ) { UI . log . error ( 'Error inserting fact ' + s + ':\n\t' + e + '\n' ) return } s = kb . add ( s . subject , s . predicate , kb . literal ( this . lastModified . value ) , s . why ) } else { if ( this . statIsInverse ) { UI . log . error ( "Invalid Input: a literal can't be a subject in RDF/XML" ) this . backOut ( ) return } var s1 , s2 , s3 switch ( obj . termType ) { case 'Literal' : // generate path and nailing from current values // TODO: DEFINE ERROR CALLBACK var valueCache = this . lastModified . value trCache = UI . utils . ancestor ( this . lastModified , 'TR' ) var oldValue = this . lastModified . defaultValue s2 = $rdf . st ( s . subject , s . predicate , kb . literal ( this . lastModified . value ) , s . why ) try { UI . store . updater . update ( [ s ] , [ s2 ] , function ( uri , success , errorBody ) { if ( success ) { obj . value = valueCache } else { UI . log . warn ( 'Error occurs while editing ' + s + '\n\n' + errorBody ) trCache . lastChild . textContent = oldValue } trCache . lastChild . className = trCache . lastChild . className . replace ( /  pendingedit / g , '' ) } ) } catch ( e ) { UI . log . warn ( 'Error occurs while editing ' + s + ':\n\t' + e ) return } // obj.value=this.lastModified.value; // UserInputFormula.statements.push(s); break case 'BlankNode' : // a request refill with text // var newStat var textTerm = kb . literal ( this . lastModified . value , '' ) // <Feature about="labelChoice"> if ( s . predicate . termType === 'Collection' ) { // case: add triple   ????????? Weird - tbl var selectedPredicate = s . predicate . elements [ 0 ] //    @@ TBL elements is a list on the predicate?? if ( kb . any ( undefined , selectedPredicate , textTerm ) ) { if ( ! e ) { // keyboard var tdNode = this . lastModified . parentNode e = { } e . pageX = UI . utils . findPos ( tdNode ) [ 0 ] e . pageY = UI . utils . findPos ( tdNode ) [ 1 ] + tdNode . clientHeight } this . showMenu ( e , 'DidYouMeanDialog' , undefined , { 'dialogTerm' : kb . any ( undefined , selectedPredicate , textTerm ) , 'bnodeTerm' : s . subject } ) } else { s1 = UI . utils . ancestor ( UI . utils . ancestor ( this . lastModified , 'TR' ) . parentNode , 'TR' ) . AJAR_statement s2 = $rdf . st ( s . subject , selectedPredicate , textTerm , s . why ) var type = kb . the ( s . subject , rdf ( 'type' ) ) s3 = kb . anyStatementMatching ( s . subject , rdf ( 'type' ) , type , s . why ) // TODO: DEFINE ERROR CALLBACK // because the table is repainted, so... trCache = UI . utils . ancestor ( UI . utils . ancestor ( this . lastModified , 'TR' ) , 'TD' ) . parentNode try { UI . store . updater . update ( [ ] , [ s1 , s2 , s3 ] , function ( uri , success , errorBody ) { if ( ! success ) { console . log ( 'Error occurs while editing ' + s1 + '\n\n' + errorBody ) outline . UserInput . deleteTriple ( trCache . lastChild , true ) // @@@@ This } } ) } catch ( e ) { console . log ( 'Error occurs while editing ' + s1 + ':\n\t' + e ) return } kb . remove ( s ) kb . add ( s . subject , selectedPredicate , textTerm , s . why ) // was: newStat = // a subtle bug occurs here, if foaf:nick hasn't been dereferneced, // this add will cause a repainting } var enclosingTd = UI . utils . ancestor ( this . lastModified . parentNode . parentNode , 'TD' ) const defaultPane = panes . default // @@ check outline . outlineExpand ( enclosingTd , s . subject , { 'pane' : defaultPane , 'already' : true } ) outline . walk ( 'right' , outline . focusTd ) // </Feature> } else { this . fillInRequest ( 'object' , this . lastModified . parentNode , kb . literal ( this . lastModified . value ) ) return // The new Td is already generated by fillInRequest, so it's done. } break } } } else if ( this . lastModified . isNew ) { // generate 'Request', there is no way you can input ' (Please Input) ' var trNode = UI . utils . ancestor ( this . lastModified , 'TR' ) var reqTerm = this . generateRequest ( '(To be determined. Re-type of drag an object onto this field)' ) var preStat = trNode . previousSibling . AJAR_statement // the statement of the same predicate this . formUndetStat ( trNode , preStat . subject , preStat . predicate , reqTerm , preStat . why , false ) // this why being the same as the previous statement this . lastModified = null // UI.log.warn("test .isNew)"); return } else if ( s . predicate . termType === 'Collection' ) { kb . removeMany ( s . subject ) var upperTr = UI . utils . ancestor ( UI . utils . ancestor ( this . lastModified , 'TR' ) . parentNode , 'TR' ) preStat = upperTr . AJAR_statement reqTerm = this . generateRequest ( '(To be determined. Re-type of drag an object onto this field)' ) this . formUndetStat ( upperTr , preStat . subject , preStat . predicate , reqTerm , preStat . why , false ) outline . replaceTD ( outline . outlineObjectTD ( reqTerm , defaultpropview ) , upperTr . lastChild ) this . lastModified = null return } else /*
      if ((s.object.termType === 'BlankNode' && !this.statIsInverse) ||
                  s.subject.termType === 'BlankNode' && this.statIsInverse) {
        this.backOut()
        return
      */ if ( this . statIsInverse ) { if ( s . subject . termType === 'BlankNode' ) { this . backOut ( ) return } } else { if ( s . object . termType === 'BlankNode' ) { this . backOut ( ) return } } // case modified - literal modification only(for now). trNode = UI . utils . ancestor ( this . lastModified , 'TR' ) // var defaultpropview = this.views.defaults[s.predicate.uri] if ( ! this . statIsInverse ) { // this is for an old feature // outline.replaceTD(outline.outlineObjectTD(s.object, defaultpropview),trNode.lastChild); outline . replaceTD ( outline . outlineObjectTD ( kb . literal ( this . lastModified . value ) , defaultpropview ) , trNode . lastChild ) } else { outline . replaceTD ( outline . outlineObjectTD ( s . subject , defaultpropview ) , trNode . lastChild ) } if ( this . lastModified . value !== this . lastModified . defaultValue ) { trNode . lastChild . className += ' pendingedit' } // trNode.AJAR_statement=s;//you don't have to set AJAR_inverse because it's not changed // This is going to be painful when predicate-edit allowed this . lastModified = null }
/* goes here when either this is a literal or escape from menu and then input text
/ * goes here when either this is a literal or escape from menu and then input text