2017-01-13 8 views
0

私は基本的な買い物リストアプリを作っていて、壁に入っています。プログラムは黙って失敗し、ブレークポイントなどでチェックすると、75行目でnewItemが未定義であることがわかりました。jQuery .val()でこの変数に未定義となっているのはなぜですか?

ステートメント内のその他すべてが正しく定義されています。私が間違って行った何かの手掛かり?

ここでindex.jsです:

'use strict'; 

var state = { 
    items: [] 
}; 

var listItemTemplate = (
    '<li>' + 
     '<span class="shopping-item js-shopping-item"></span>' + 
     '<div class="shopping-item-controls">' + 
      '<button class="js-shopping-item-toggle">' + 
       '<span class="button-label">check</span>' + 
      '</button>' + 
      '<button class="js-shopping-item-delete">' + 
       '<span class="button-label">delete</span>' + 
      '</button>' + 
      '</div>' + 
    '</li>' 
); 

// state modification functions 
var stateHelper = { 
    addItem: function(state, item) { 
     state.items.push({ 
      displayName: item, 
      checkedOff: false 
     }); 
    }, 
    getItem: function(state, itemIndex) { 
     return state.items[itemIndex]; 
    }, 
    deleteItem: function(state, item) { 
     state.items.splice(itemIndex, 1); 
    }, 
    updateItem: function(state, item) { 
     state.items[itemIndex] = newItemState; 
    } 
} 

// render functions 
var renderHelper = { 
    renderItem: function(item, itemId, itemTemplate, itemDataAttr) { 
     var element = $(itemTemplate); 
     element.find('.js-shopping-item').text(item.displayName); 
     console.log("item.displayName: " + item.displayName) 
     console.log("item: " + item) 
     if (item.checkedOff) { 
      element.find('.js-shopping-item').addClass('shopping-item__checked'); 
     } 
     element.find('.js-shopping-item-toggle') 
     element.attr(itemDataAttr, itemId); 
     // try `element.find('.js-shopping-item-toggle').attr(itemDataAttr, itemId);` instead and see if it works 
     console.log("itemDataAttr: " + itemDataAttr) 
     return element; 
    }, 
    renderList: function(state, listElement, itemDataAttr) { 
     var itemsHTML = state.items.map(
      function(item, index) { 
       //what determines the index here? 
       console.log("index: " + index) 
       return renderItem(item, index, listItemTemplate, itemDataAttr); 
      }); 
      listElement.html(itemsHTML); 
    } 
} 

// event listeners 

var eventHelper = { 
    handleItemAdds: function(formElement, newItemIdentifier, itemDataAttr, listElement, state) { 
     formElement.submit(function(event) { 
      event.preventDefault(); 
      var newItem = formElement.find(newItemIdentifier).val(); 
      console.log(newItem) 
      stateHelper.addItem(state, newItem); 
      console.log(newItemIdentifier) 
      this.reset(); 
     }); 
    }, 
    handleItemDeletes: function(formElement, removeIdentifier, itemDataAttr, listElement, state) { 
     listElement.on('click', removeIdentifier, function(event) { 
      var itemIndex = parseInt($(this).closest('li').attr(itemDataAttr)); 
      console.log("this: " + this); 
      console.log("$(this).closest('li').attr(itemDataAttr " + $(this).closest('li').attr(itemDataAttr)); 
      stateHelper.deleteItem(state, itemIndex); 
      renderList(state, listElement, itemDataAttr); 
      console.log("what is itemDataAttr? it is: " + itemDataAttr) 
     }) 
    }, 
    handleItemToggles: function(listElement, toggleIdentifier, itemDataAttr, state) { 
     listElement.on('click', toggleIdentifier, function(event) { 
      var itemId = $(event.currentTarget.closest('li')).attr(itemDataAttr); 
      var oldItem = stateHelper.getItem(state, itemId); 

      stateHelper.updateItem(state, itemId, { 
       displayName: oldItem.displayName, 
       checkedOff: !oldItem.checkedOff 
      }); 
      renderHelper.renderList(state, listElement, itemDataAttr) 
     }); 
    } 
} 


$(function() { 
    var formElement = $('#js-shopping-list-form'); 
    var listElement = $('.js-shopping-list'); 

    //id of input containing list items 
    var newItemIdentifier = "#js-new-item"; 

    //in listItemTemplate above; the delete button has this class 
    var removeIdentifier = ".js-shopping-item-delete"; 

    //stores id of list item 
    var itemDataAttr = "data-list-item-id"; 

    var toggleIdentifier = ".js-shopping-list-toggle" 

    eventHelper.handleItemAdds(formElement, newItemIdentifier, itemDataAttr, listElement, state); 
    eventHelper.handleItemDeletes(formElement, removeIdentifier, itemDataAttr, listElement, state); 
    eventHelper.handleItemToggles(listElement, toggleIdentifier, itemDataAttr, state); 
}); 

そして、ここでは、参考のためのindex.htmlです:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <title>Shopping List</title> 

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css"> 
    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"> 

    <link rel="stylesheet" href="main.css"> 
</head> 
<body> 

    <div class="container"> 
    <h1>Shopping List</h1> 

    <form id="js-shopping-list-form"> 
     <label for="shopping-list-entry">Add an item</label> 
     <input type="text" name="shopping-list-entry" id="shopping-list-entry" placeholder="e.g., broccoli"> 
     <button type="submit">Add item</button> 
    </form> 

    <ul class="shopping-list"> 
    </ul> 
    </div> 
    <script src="jquery-3.1.1.js"></script> 
    <script type="text/javascript" src="index.js"></script> 
</body> 
</html> 
+2

'newItemIdentifier'は'#js-new-item'です。あなたのコードでこの要素を見つけることができません。何か迷っていますか? –

+0

'#js-new-item'要素をどこかに動的に追加していますか?あなたのエラーを投げている行で、あなたはこの要素の価値を探していますが、あなたのHTMLのどこにも表示されません。私はJSを徹底的に調べたわけではありませんが、 'append'や' appendTo'のようなものは見当たらず、存在しない要素のval()を取得しようとしています。 **編集:** axel.michelそれに私を打つ:^) – Santi

+0

もちろん!ありがとう、私はそれを更新することを忘れました。私は助けに感謝します。 – Alacritas

答えて

0

Alacritas、

私はあなたのことをどこでもあなたのビューで表示されません実際にそのアクセサ(#js-new-item)と一致するidを持つ要素があります。

あなたのコメントは入力ボックスに属していると言っていますが、あなたのhtmlにある入力ボックスにはそのIDはありません。

"#js-new-item"という文字列を "#shopping-list-entry"に更新する必要があると思います。

+0

パーフェクト!これはまさに私が逃したものです。 – Alacritas

関連する問題