2014-01-23 2 views
3

У меня есть следующая проблема:Размещение кода в моем массиве Javascript

Я создал форму с большим количеством полей ввода. Если пользователь набирает 1, он сразу же отображает цену. Мой код это так:

var priceMargherita = 7; 
    var numPizzaMargheritaInput = document.getElementById('countMargherita'); 
    var priceMargheritaLabel = document.getElementById('totalMargherita'); 

    function onNumPizzaMargheritaInputChange(e){ 

     var totalMargherita = priceMargherita * parseInt(e.target.value); 
     var formattedPrice = '\u20ac '+totalMargherita.toFixed(2); 

     priceMargheritaLabel.innerHTML = ''; 
     priceMargheritaLabel.appendChild(document.createTextNode(formattedPrice)); 
    } 
    numPizzaMargheritaInput.addEventListener('change', onNumPizzaMargheritaInputChange, false); 

и ставит цену, как это:

<td>Pizza Margherita</td> 
<td><input type="number" id="countMargherita" class="formnumbers" name="PizzaMargherita" onChange="validateForm(this)" min="1" max="99"/></td> 
<td><span id="totalMargherita"></span></td> 

Теперь моя проблема заключается в том, что у меня есть 11 продуктов, как эта Pizza Margherita. И на данный момент у меня есть 11 фрагментов кода, таких как верхний. Я думаю, что это можно сделать в массиве, поскольку единственное, что меняется, - это некоторые имена.

Исправьте меня, если я ошибаюсь, так как im нигде не ощущается в JS или массивах.

Любая помощь очень ценится!

+0

Я должен сказать, его сочный код, действительно. – DontVoteMeDown

ответ

1

Для меня самый простой способ сделать это - НЕ использовать массивы или идентификаторы.

Если вы можете изменить HTML, вы должны добавить цену в качестве данных-атрибута, а затем вы можете иметь общий код:

<td>Pizza Margherita</td> 
<td><input type="number" class="formnumbers" name="PizzaMargherita" 
      onChange="changeTotalFromCount(this)" min="1" 
      max="99" data-unitPrice="7" /></td> 
<td></td> 

JS:

function changeTotalFromCount(input) { 
    var unitPrice = parseFloat(input.getAttribute("data-unitPrice")); 
    var count = input.value; 

    var price = unitPrice * count; 
    var formattedPrice = '\u20ac ' + price.toFixed(2); 

    var label = input.parentNode.nextElementSibling; 
    label.innerHTML = ''; 
    label.appendChild(document.createTextNode(formattedPrice)); 
} 
+0

Есть 1 проблема, я уже использую событие onChange с именем validateForm (this). Могу ли я просто добавить другое событие в onChange? –

+0

Nevermind, получил его, и он отлично работает, спасибо большое –

0

Вместо того, чтобы массивы, я думаю, что слово, которое вы ищете, это петли. Вот путь к фактору вашей программы, используя объект и цикл:

var prices = { 
    Margherita: 7, 
    Hawaiian: 7, 
    NewYork: 8 
}; 

for (var pizzaType in prices) { 
    var inputElement = document.getElementbyId('count' + pizzaType); 
    var labelElement = document.getElementbyId('total' + pizzaType); 

    inputElement.addEventListener('change', function(event) { 
    var total = prices[pizzaType] * parseInt(event.target.value); 
    var formattedPrice = '\u20ac ' + total.toFixed(2); 

    labelElement.innerHTML = ''; 
    labelElement.appendChild(document.createTextNode(formattedPrice)); 
    }, false); 
} 

Я решил использовать анонимную функцию вместо имени одного, так как это является наиболее распространенной практикой со слушателями событий.

0

Массив не самый эффективный способ решить проблему. Вам будет лучше с более обобщенной функцией, которая имеет необходимую информацию (событие, цену и идентификатор элемента для отображения цены) в качестве параметров. Затем используйте массив объектов для инициализации всего. Что-то вроде этого:

var pizzas = [ 
    { 
     pizza: 'margherita', 
     price: 7, 
     input: 'countMargherita', 
     label: 'totalMargherita' 
    }, 
    { 
     pizza: 'pepperoni', 
     price: 10, 
     input: 'countPepperoni', 
     label: 'totalPepperoni' 
    } 
] 

function calculatePrice(e, price, label) { 
    var total = price * parseInt(e.target.value); 
    var formattedPrice = '\u20ac '+total.toFixed(2); 

    var outputElement = document.getElementById(label); 
    outputElement .innerHTML = ''; 
    outputElement .appendChild(document.createTextNode(formattedPrice)); 
} 

Затем перебирать, что pizzas массив, чтобы связать все вверх:

for(var i = 0, l = pizzas.length; i < l; i++) { 
    (function(pizza) { 
     document.getElementById(pizza.input).addEventListener('change', function(e) { 
      calculatePrice(e, pizza.price, pizza.label); 
     }, false); 
    })(pizzas[i]); 
} 

выше использует замыкание, чтобы избежать проблем из-за видимости переменной в JavaScript; i ограничен областью действия, поскольку на уровне кадра не отображается. Поскольку обработчик событий является по существу отложенным действием, значение i, когда это выполняется, также будет последним значением i, если вы его не используете.

+0

Я не знаю, что я делаю что-то неправильно, но я не могу заставить его работать. Это просто показывает мне пустые ценовые промежутки. –

+0

@Farewyth Вы могли бы быть, или я допустил ошибку при написании кода (я не тестировал его, это просто с головы). Я посмотрю, смогу ли я когда-нибудь бросить скрипку и разобраться в проблеме. EDIT: [скрипка] (http://jsfiddle.net/DJp9T/), похоже, работает нормально. –

+0

Nevermind, проблема была на моем конце, спасибо за усилия! –

0

Сделайте более общую функцию для расчета цены, например onNumPizzChange, которая принимает имя базового элемента, например. «Маргерита». В этой функции, извлечь ваш элемент как

var inputElm = document.getElementById('count'+elmBase); 

затем настроить события, окружив эту функцию с другим так, как:

document.getElementById('numPizzaMargheritaCount').addEventListener('change', function(){ onNumPizzaChange('Margherita')}, false); 

Имеет ли это смысл?

Удачи вам!

Смежные вопросы