I'm working on this eCommerce project where I need to calculate "shipping costs" if a particular checkbox is checked.
Here's the code for the checkbox :-
<div class="alert alert-info">
<p>Shipping Outside Lagos (N2, 000)</p>
<input type="checkbox" name="shipping" id="shipping">
</div>
How can I write the jQuery function, so that when the input is checked..I can get the value in a variable. Suppose the default value is 2000, how would I be able to get $amount=2000 (if checked) and $amount remains 0 if unchecked.
Due to my limited knowledge in jQuery / JavaScript, I'm unable to find a solution for it.
Search didn't help either.
Any suggestions are welcome.
var amount = $('#shipping').is(':checked') ? 2000 : 0;
$('#shipping').on('change', function() {
amount = this.checked ? 2000 : 0;
});
// use amount
You can do:
var shippingAmt = 0;
$("#shipping").change(function() {
shippingAmt = this.checked ? 2000 : 0;
});
I'd suggest using a function to determine the cost of items. You could have an abstract of determining costs which would run through a few or several conditions to calculate 'add ons' so to speak.
So you'd have your initial total of say $500.99, then run that value through something like calculateTotalValue(value)
It would check if any add-ons were checked in the form, and add their values to the initial value.
This would allow you to have any number of extras, like shipping, or even add-ons/upgrades for the product itself, and you'd be able to fetch the total without fail in each case. You could have a generic way of stipulating that a field is an 'add on' so you wouldn't need to maintain a list, like so:
<input type="checkbox" rel="add-on" data-add-on-type="shipping" value="500">
Then in your function,
calculateTotalValue(value) {
$.each($('input[rel="add-on"]'), function(i) {
// You probably want some error checking here
value += this.val();
});
return value;
}
If necessary you could use data-add-on-type to keep track of where costs comes from to output a list for the user, as well.
Related
I want to validate user input so he only provides numbers from a certain range with 0,5 steps. But I want my website to do it every time user swaps to another input form, not after he sends the data to my view. Can you give a hint of how should it be done? I don't know Javascript but I know there is onfocusout DOM event. Is it correct approach to use it, check whether or not value is valid and display an alarm based on that?
In general, there's no problem using onfocusevent.
Here's a hint on how to do this:
Create the input field
Add the onfocusout event handler and assign it a JavaScript function
Define the JavaScript function responsible for the validation process (which is, the same function we talked about in step 2)
This function takes the value inside the field and compares it, if it's not inside the range you desire then you can show an alarm or something like this.
I made a demo that doesn't involve alarming the user but instead it colors the border with either green or red, when you get desperate pay it a visit:
<input type="number" id="field1" onfocusout="validateField(0, 100, 'field1')"/><br/><br/>
<input type="number" id="field2" onfocusout="validateField(200, 300, 'field2')"/><br/><br/>
<input type="number" id="field3" onfocusout="validateField(400, 500, 'field3')"/><br/><br/>
<script>
function validateField(min, max, id) {
const value = document.getElementById(id).value;
if (value < min || value > max) {
document.getElementById(id).style.borderColor = "red";
}
else {
document.getElementById(id).style.borderColor = "lime";
}
}
</script>
I try to do simple code for guessing notes by ear. I have tabs with several empty input fields and you need to put right numbers in these fields according to certain melody (for guitar fretboard) . One button shows first note, another button checks whether you put right or wrong number and depend on it approves or erase your number.
I know how to check every input field using its id's but can i do it such way that when i push 2nd button it get value from selected input and compare it to its placeholder or value attribute?
It is my codepen
https://codepen.io/fukenist/pen/BxJRwW
Script part
function showfirst() {
document.getElementById("fst").value = "12"
}
function show1other() {
var snote = document.getElementById("scnd").value;
if (snote == 9 ){
document.getElementById("scnd").value = "9";
}
else {
document.getElementById("scnd").value = "";
}
}
You can use document.querySelectorAll() to get all your inputs and loop over them.
Sample:
// Get all inputs as an array (actually NodeList, to be precise; but it behaves similar to an array for this use case)
var inputs = document.querySelectorAll('input');
// Function to reveal the first input's value
function showFirst(){
inputs[0].value = inputs[0].dataset.v;
}
// Function to check all values and clear input if wrong
function checkAll(){
inputs.forEach(function(input){
if(input.dataset.v !== input.value){
// Wrong answer, clear input
input.value = '';
}
});
}
<input data-v="12" size="2" value=""/>
<input data-v="9" size="2" value=""/>
<input data-v="8" size="2" value=""/>
<br/>
<button onclick="showFirst()">Show First</button>
<button onclick="checkAll()">Check All</button>
Notes:
I have used data-v to store the correct answer instead of placeholder as that attribute has a semantically different meaning
It may be out of turn but my two cents: Writing out entire songs like this by hand may become tedious. Consider using a JSON string or something similar to map out the tabs and use a templating framework to align them.. Some things you may need to look out for while designing something like this : Alignment of notes (successive notes, simultaneous notes), timing of the song, special moves like slide, hammer on etc.
It may be a better idea to make the Guitar Strings be a background element (either as a background-image or as absolutely positioned overlapping divs) (so You don't have to worry about the lines going out of alignment)
Reference:
HTMLElement.dataset
document.querySelectorAll
I am trying to replace some text in an input field using JS but the view model overrides my commands each time. This is the HTML I start with:
<td class="new-variants-table__cell" define="{ editVariantPrice: new Shopify.EditVariantPrice(this) }" context="editVariantPrice" style="height: auto;">
<input type="hidden" name="product[variants][][price]" id="product_variants__price" value="25.00" bind="price" data-dirty-trigger="true">
<input class="mock-edit-on-hover tr js-no-dirty js-variant-price variant-table-input--numeric" bind-event-focus="onFocus(this)" bind-event-blur="onBlur(this)" bind-event-input="onInput(this)">
</td>
I run this JS:
jQuery('#product_variants__price').siblings().removeAttr('bind-event-focus');
jQuery('#product_variants__price').siblings().removeAttr('bind-event-input');
jQuery('#product_variants__price').siblings().removeAttr('bind-event-blur');
jQuery('#product_variants__price').siblings().focus()
jQuery('#product_variants__price').siblings().val("34.00");
jQuery('#product_variants__price').val("34.00");
And I'm left with the following HTML:
<td class="new-variants-table__cell" define="{ editVariantPrice: new Shopify.EditVariantPrice(this) }" context="editVariantPrice" style="height: auto;">
<input type="hidden" name="product[variants][][price]" id="product_variants__price" value="34.00" bind="price" data-dirty-trigger="true">
<input class="mock-edit-on-hover tr js-no-dirty js-variant-price variant-table-input--numeric">
</td>
The problem is that each time I click the input field the value is reverted to what it was when the page loaded.
I've also tried running the command in the parent td along with my value change, to simulate the editing of a variant and preventing default with no success:
jQuery('#product_variants__price').siblings().bind('input', function (e) {
e.preventDefault();
return false;
});
jQuery('#product_variants__price').siblings().bind('focus', function (e) {
e.preventDefault();
return false;
});
jQuery('#product_variants__price').siblings().focus()
jQuery('#product_variants__price').siblings().val("£34.00");
jQuery('#product_variants__price').val("£34.00");
jQuery('#product_variants__price').siblings().keydown()
Parent td function:
new Shopify.EditVariantPrice(jQuery('#product_variants__price').parent())
So how can I successfully edit this value in the inputs and also update the Shopify view model?
You can try this for yourself by going here:
https://jebus333.myshopify.com/admin/products/2521183043
login jebus333#mailinator.com
password shop1
EDIT: I've tried to find the view model on the page but with no success. Plus, there are no network calls when editing the values in the input fields, leading me to believe the values are being pulled back from somewhere on page.
Try this:
var old = Shopify.EditVariantPrice.prototype.onFocus;
Shopify.EditVariantPrice.prototype.onFocus = function(t) {
this.price = '50.00'; // Use the price you want here
old.call(this, t);
};
jQuery('#product_variants__price').siblings().triggerHandler("focus");
jQuery('#product_variants__price').siblings().triggerHandler("blur");
If it works for you, it's possible that the following will be sufficient:
Shopify.EditVariantPrice.prototype.onFocus = function(t) {
this.price = '50.00'; // Use the price you want here
};
Well, there is a kind of a dirty solution...
First of all you'll need a sendkeys plugin. In fact that means you'll need to include this and this JS libraries (you can just copy-paste them in the console to test). If you don't want to use the first library (I personally find it quite big for such a small thing) you can extract only the key things out of it and use only them.
The next step is creating the function which is going to act like a real user:
function input(field, desiredValue) {
// get the currency symbol while value is still pristine
var currency = field.val()[0];
// move focus to the input
field.click().focus();
// remove all symbols from the input. I took 10, but of course you can use value.length instead
for (var i = 0; i < 10; i++) field.sendkeys("{backspace}");
// send the currency key
field.sendkeys(currency);
// send the desired value symbol-by-symbol
for (var i = 0; i < desiredValue.length; i++) field.sendkeys(desiredValue[i]);
}
Then you can simply call it with the value you wish to assign:
input($("#product_variants__price").next(), "123.00");
I did not really manage to fake the blur event because of lack of the time; that is why I was forced to read the currency and pass .00 as a string. Anyway you already have a way to go and a quite working solution.
Looks like you're trying to automate editing of variant prices of products in Shopify's admin panel.
Instead of playing around with the DOM of Shopify's admin page, I'll suggest using Shopify's bulk product editor which lets you set prices of all variants in a single screen. I feel that you'll have better luck setting the variant prices using JavaScript on the bulk product editor page.
Clicking on the 'Edit Products' button as shown in the screenshot below will open the bulk product editor.
Also check if browser based macro recording plugins like iMacro can be of your help (you can also code macros with JS in iMacro).
You can see in the paper form attached what I need to convert into a web form. I want it to show the check boxes and disable the input fields unless the user checks the box next to it. I've seen ways of doing this with one or two elements, but I want to do it with about 20-30 check/input pairs, and don't want to repeat the same code that many times. I'm just not experienced enough to figure this out on my own. Anyone know anywhere that explains how to do this? Thanks!
P.S. Eventually this data is all going to be sent through an email with PHP.
I don't think this is a good idea at all.
Think of the users. First they have to click to enter a value. So they always need to change their hand from mouse to keyboard. This is not very usable.
Why not just give the text-fields? When sending with email you could just leave out the empty values.
in your HTML :
//this will be the structure of each checkbox and input element.
<input type="checkbox" value="Public Relations" name="skills" /><input type="text" class="hidden"/> Public Relations <br/>
in your CSS:
.hidden{
display:none;
}
.shown{
display:block;
}
in your jQuery:
$('input[type=checkbox]').on('click', function () {
// our variable is defined as, "this.checked" - our value to test, first param "shown" returns if true, second param "hidden" returns if false
var inputDisplay = this.checked ? 'shown' : 'hidden';
//from here, we just need to find our next input in the DOM.
// it will always be the next element based on our HTML structure
//change the 'display' by using our inputDisplay variable as defined above
$(this).next('input').attr('class', inputDisplay );
});
Have fun.
Since your stated goal is to reduce typing repetitive code, the real answer to this thread is to get an IDE and the zen-coding plug in:
http://coding.smashingmagazine.com/2009/11/21/zen-coding-a-new-way-to-write-html-code/
http://vimeo.com/7405114
I'm fairly new to JavaScript and am trying to write some code that lists three price options in a form, as checkboxes. If both of the first two are selected, I want the total price to drop by a certain amount.
My code is based on the code in this question:
Javascript checkboxes incorrect calculating
They reset the base value by a date variable. I assume that if I have a function that sets the base to a negative value if those two boxes are checked, that would achieve what I want. I'd also like the output to have an additional tag of 'save (x) per month' when this happens.
However I'm not sure how to go about relating the variable to the checkboxes.. do I need to use jquery as per how to change the value of a variable based on a select option:selected?
Jquery is never necessary, but it is always a plus. since you are learning javascript, i would recommend not using the framework yet.
First you need a form (it would be better if you showed us what your form looks like):
<form>
<input type="checkbox" id="first" /><label for="first">First Box</label> <br>
<input type="checkbox" id="second" /><label for="second">First Box</label> <br>
<input type="text" id="output" value="5.00"/>
</form>
Now the javascript
<script type="text/javascript">
var first = document.getElementById("first");
var second = document.getElementById("second");
first.onchange = function () {
if (this.checked == true) {
document.getElementById("output").value = "new Value";
}else {
document.getElementById("output").value = "other Value";
}
}
... the same can be done for 'second' ....
</script>
I'm assuming you are modifying your recalculate() function from your earlier question. In that function, after you get your sum, add this to apply the discount:
if ($("#chkBox1,#chkBox2").filter(":checked").length == 2)
{
sum -= discount;
}
To write the message to your output, modify your $("#output").html(sum) code to this:
$("#output").html(sum + " Save $" + discount + " per month");
if (document.getElementById('checkBox1').checked && document.getElementById('checkBox2').checked) {
// Change the price
}
There are many ways to address this issue. As a reminder before I get into it, never do something like 'calculating price' on the client-side. That is, you can calculate the price so show the user, but any real calculations should be done on the server side (as clients can adjust and manipulate form submissions).
I created a simple example that will tally the results of checked checkboxes (and simply displays the result). There are lots of ways you can manipulate this code to fit your purpose. I have used jQuery, but there are other interesting options for this problem (check out KnockoutJS, for instance).
<input type="checkbox" class="adjust one" data-value="1.00" id="so1" /> <label for="so1">$1.00</label> <br/>
<input type="checkbox" class="adjust two" data-value="2.00" id="so2" /> <label for="so2">$2.00</label><br/>
<input type="checkbox" class="adjust one" data-value="3.00" id="so3" /> <label for="so3">$3.00</label>
<p>
Total: <span class="total"></span>
</p>
Then, you want to include the following JavaScript (along with the jQuery library).
var total;
var calculateTotal = function() {
total = 0.0;
$('input[type="checkbox"]:checked').each(function() {
total += parseFloat($(this).data('value'));
});
$('.total').text(total);
};
$(document).ready(function() {
$('input[type="checkbox"]').live('change', function() {
calculateTotal();
});
calculateTotal(); //do it for initial price
});
calculateTotal() will calculate a total based on the checkboxes (inputs of type checkbox) which match the selector "checked". This then pulls the data attribute "value" from each checkbox and calculates a total based on that number. The logic for your problem is likely to differ, but simply adjusting calculateTotal should handle this. Finally, the calculateTotal function gets called whenever a checkbox is 'changed' (and once initially).
Hopefully this should be a big help in getting you up and running. Here is a JSFiddle live demonstration.