scripts/item/item-sheet.js
/**
   * Activate event listeners using the prepared sheet HTML
   * @param html {HTML}   The prepared HTML object ready to be rendered into the DOM
   */
Activate event listeners using the prepared sheet HTML
@param html {HTML}   The prepared HTML object ready to be rendered into the DOM
Activate event listeners using the prepared sheet HTML @param html { HTML } The prepared HTML object ready to be rendered into the DOM
activateListeners(html)
  {
    super.activateListeners(html);
    html.find('input[type="checkbox"]').change(event => this._onSubmit(event));
    html.find('.lore-input').change(async event =>
      {
        let inputLore = event.target.value;
        for (let lore in WNG.magicLores)
        {
          if (inputLore == WNG.magicLores[lore])
          {
            await this.item.update({'data.lore.value': lore});
            return;
          }
        }
        await this.item.update({'data.lore.value': inputLore});
      }),
      html.find('.char-checkbox').click(async event =>
      {
        this._onSubmit(event);
        let charChanged = $(event.currentTarget).attr("name")
        let characteristicList = duplicate(this.item.data.data.characteristics);
        if (characteristicList.includes(charChanged))
          characteristicList.splice(characteristicList.findIndex(c => c == charChanged));
        else 
          characteristicList.push(charChanged);
        await this.item.update({'data.characteristics': characteristicList})
      }),
      html.find(".item-checkbox").click(async event =>
      {
        this._onSubmit(event);
        let target = $(event.currentTarget).attr("data-target");
        let path = target.split(".");
        this.item.update({[`data.${target}`]: !this.item.data.data[path[0]][path[1]]})
      }),
      html.find('.csv-input').change(async event =>
      {
        this._onSubmit(event);
        let list = event.target.value.split(",").map(function (item)
        {
          return item.trim();
        });
        switch (event.target.attributes["data-dest"].value)
        {
          case 'skills':
            {
              await this.item.update({'data.skills': list});
            }
            break;
          case 'earning':
            {
              this.item.update({'data.incomeSkill': []});
              let earningSkills = [];
              for (let sk in list)
              {
                let skillIndex = this.item.data.data.skills.indexOf(list[Number(sk)])
                if (skillIndex == -1)
                  continue;
                else
                  earningSkills.push(skillIndex);
              }
              await this.item.update({'data.incomeSkill': earningSkills});
            }
            break;
          case 'talents':
            {
              await this.item.update({'data.talents': list});
            }
            break;
          case 'trappings':
            {
              await this.item.update({'data.trappings': list});
            }
            break;
        }
      });
    html.on("change", ".item-name", ev => {
      if (this.item.type != "skill" || !this.item.actor || this.item.data.data.grouped.value != "isSpec")
        return;
      if (ev.target.value == this.item.name)
        return
      let currentCareer = duplicate(this.item.actor.data.items.filter(i => i.type == "career").find(i => i.data.current.value));
      if(currentCareer && currentCareer.data.skills.includes(this.item.name))
        currentCareer.data.skills[currentCareer.data.skills.indexOf(this.item.name)] = ev.target.value;
      else 
        return;
      let oldName = this.item.name
      new Dialog({
          title : game.i18n.localize("SHEET.CareerSkill"),
          content: `<p>${game.i18n.localize("SHEET.CareerSkillPrompt")}</p>`,
          buttons: {
            yes: {
              label: "Yes",
              callback: async dlg => {
                ui.notifications.notify(`Changing ${oldName} to ${ev.target.value} in ${currentCareer.name}`)
                this.item.actor.updateEmbeddedEntity("OwnedItem", currentCareer)
              }
            },
            no: {
              label: "No",
              callback: async dlg => {
                return;
              }
            },
          },
          default: 'yes'
        }).render(true);
      });
    html.on("click", ".chat-roll", ev =>
    {
      WNG_Utility.handleRollClick(ev)
    })
    html.on("click", ".symptom-tag", ev =>
    {
	  WNG_Utility.handleSymptomClick(ev)
    })
    html.on("click", ".condition-chat", ev =>
    {
      WNG_Utility.handleConditionClick(ev)
    })
    html.on('mousedown', '.table-click', ev =>
    {
      WNG_Utility.handleTableClick(ev)
    })
  }
activateListeners ( html ) { super . activateListeners ( html ) ; html . find ( 'input[type="checkbox"]' ) . change ( event => this . _onSubmit ( event ) ) ; html . find ( '.lore-input' ) . change ( async event => { let inputLore = event . target . value ; for ( let lore in WNG . magicLores ) { if ( inputLore == WNG . magicLores [ lore ] ) { await this . item . update ( { 'data.lore.value' : lore } ) ; return ; } } await this . item . update ( { 'data.lore.value' : inputLore } ) ; } ) , html . find ( '.char-checkbox' ) . click ( async event => { this . _onSubmit ( event ) ; let charChanged = $ ( event . currentTarget ) . attr ( "name" ) let characteristicList = duplicate ( this . item . data . data . characteristics ) ; if ( characteristicList . includes ( charChanged ) ) characteristicList . splice ( characteristicList . findIndex ( c => c == charChanged ) ) ; else characteristicList . push ( charChanged ) ; await this . item . update ( { 'data.characteristics' : characteristicList } ) } ) , html . find ( ".item-checkbox" ) . click ( async event => { this . _onSubmit ( event ) ; let target = $ ( event . currentTarget ) . attr ( "data-target" ) ; let path = target . split ( "." ) ; this . item . update ( { [ ` ${ target } ` ] : ! this . item . data . data [ path [ 0 ] ] [ path [ 1 ] ] } ) } ) , html . find ( '.csv-input' ) . change ( async event => { this . _onSubmit ( event ) ; let list = event . target . value . split ( "," ) . map ( function ( item ) { return item . trim ( ) ; } ) ; switch ( event . target . attributes [ "data-dest" ] . value ) { case 'skills' : { await this . item . update ( { 'data.skills' : list } ) ; } break ; case 'earning' : { this . item . update ( { 'data.incomeSkill' : [ ] } ) ; let earningSkills = [ ] ; for ( let sk in list ) { let skillIndex = this . item . data . data . skills . indexOf ( list [ Number ( sk ) ] ) if ( skillIndex == - 1 ) continue ; else earningSkills . push ( skillIndex ) ; } await this . item . update ( { 'data.incomeSkill' : earningSkills } ) ; } break ; case 'talents' : { await this . item . update ( { 'data.talents' : list } ) ; } break ; case 'trappings' : { await this . item . update ( { 'data.trappings' : list } ) ; } break ; } } ) ; html . on ( "change" , ".item-name" , ev => { if ( this . item . type != "skill" || ! this . item . actor || this . item . data . data . grouped . value != "isSpec" ) return ; if ( ev . target . value == this . item . name ) return let currentCareer = duplicate ( this . item . actor . data . items . filter ( i => i . type == "career" ) . find ( i => i . data . current . value ) ) ; if ( currentCareer && currentCareer . data . skills . includes ( this . item . name ) ) currentCareer . data . skills [ currentCareer . data . skills . indexOf ( this . item . name ) ] = ev . target . value ; else return ; let oldName = this . item . name new Dialog ( { title : game . i18n . localize ( "SHEET.CareerSkill" ) , content : ` ${ game . i18n . localize ( "SHEET.CareerSkillPrompt" ) } ` , buttons : { yes : { label : "Yes" , callback : async dlg => { ui . notifications . notify ( ` ${ oldName } ${ ev . target . value } ${ currentCareer . name } ` ) this . item . actor . updateEmbeddedEntity ( "OwnedItem" , currentCareer ) } } , no : { label : "No" , callback : async dlg => { return ; } } , } , default : 'yes' } ) . render ( true ) ; } ) ; html . on ( "click" , ".chat-roll" , ev => { WNG_Utility . handleRollClick ( ev ) } ) html . on ( "click" , ".symptom-tag" , ev => { WNG_Utility . handleSymptomClick ( ev ) } ) html . on ( "click" , ".condition-chat" , ev => { WNG_Utility . handleConditionClick ( ev ) } ) html . on ( 'mousedown' , '.table-click' , ev => { WNG_Utility . handleTableClick ( ev ) } ) }
Activate event listeners using the prepared sheet HTML
 @param html {HTML}   The prepared HTML object ready to be rendered into the DOM
Activate event listeners using the prepared sheet HTML @param html { HTML } The prepared HTML object ready to be rendered into the DOM
// Checkbox changes // Lore input is tricky because we need to choose from a set of defined choices, but it isn't a dropdown // Go through each lore name // If lore value matches config, use that (Update the actor with the "key" value) // Otherwise, if the input isn't recognized, store user input directly as a custom lore // For a career, when characteristic checkbox is changed, ensure list of  // characteristics for that career remains valid. // If the charChanged is already in the list, remove it // If it isn't in the list, add it // Generalized checkbox update for various different items. TODO: is this needed? // This listener converts comma separated lists in the career section to arrays, // placing them in the correct location using update // find the indices of the skills that match the earning skill input, send those // values to data.incomeSkill // If the user changes a grouped skill that is in their current career, // offer to propagate that change to the career as well. // If no change // If career has the skill that was changed, change the name in the career // if it doesn't, return // Ask the user to confirm the change // Support custom entity links