jQuery / JS form issue - javascript

I have a HTML form which I need help with adding and removing data using jQuery (or JavaScript).
$('.purchase-car').on('click', 'button', function(event) {
event.preventDefault();
/* Act on the event */
var carName = $('.purchase-car select').val();
var carPrice = $('.purchase-car select').find(':selected').data('price');
var carQuantity = $('.purchase-car input[name="quantity"]').val();
var totalPrice = carPrice * carQuantity;
var orderToAdd = '<li>' + '<span>' + carName + ' (' + carQuantity + ')</span> <span>remove</span>' + '</li>';
$('ul').prepend(orderToAdd);
$('#payment-amount').html(total);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>volvo (1) <span>remove</span>
</li>
<li>mercedes (2) <span>remove</span>
</li>
</ul>
<p>Total Price: <span id="payment-amount">30</span>
</p>
<div class="purchase-car">
<select>
<option value="volvo" data-price="10">Volvo ( $10 )</option>
<option value="saab" data-price="20">Saab ( $20 )</option>
<option value="mercedes" data-price="10">Mercedes ( $10 )</option>
<option value="audi" data-price="30">Audi ( $30 )</option>
</select>
<input type="number" name="quantity" value="1">
<button type="submit">Add</button>
</div>
There will be one select field and one input field, once I click add (on submit) both of the values should be added in a ul as list item. I have successfully done so. But I need a calculation here.
Like, what's the total price of selected objects. Also It should subtract from total price when I remove particular object.
http://jsfiddle.net/getanwar/s7ob01o1/
Update: I don't want to insert those data directly to the DOM. Because this is a part of another form and I don't want this data to be editable from console or via developer tools. So if I could store these data into an array or an object and calculate from there would be really helpful.

Taking your update into consideration, you should create a global variable.
var vehicles = new Array;
To increase the value, in the function where you insert the vehicle add the line:
var currentValue = parseInt($("#payment-amount").html());
$("#payment-amount").html(curentValue + (carPrice * carQuantity));
vehicles.push({price: carPrice, quantity: carQuantity});
Then to update the price when you remove one:
$("ul").on("click", "li span", function() {
var index = $(this).parent().index();
var currentValue = parseInt($("#payment-amount").html());
var removeValue = vehicles[index]['price'] * vehicles[index]['quantity'];
$("#payment-amount").html(currentValue - removeValue);
vehicles.splice(index, 1);
$(this).parent().remove();
});

Related

Unable to update global variable using javascript on button click

I need to update the price global variable. I believe it may have something to do with scope. I would appreciate it if you could be of assistance in this regard.
This is the script:
var price = 0;
var nextdayClass = $('.delivery1');
var $standardClass = $('.delivery2');
var $pickupClass = $('.delivery3');
nextdayClass.on('click', function() {
var nextday = $('#nextday').data('price');
price = nextday;
console.log(price);
});
standardClass.on('click', function () {
var standard = $('#standard').data('price');
price = standard;
console.log(price);
});
pickupClass.on('click', function () {
var pickup = $('#pickup').data('price');
price= pickup;
console.log(price);
});
console.log(price);
cartTotalHTML += '<div>' +
'<ul>' +
'<li>' +
'<div>Subtotal</div>' +
'<div>' + formatMoney(total) + '</div>' +
'</li>' +
'<li>' +
'<div>Shipping</div>' +
'<div>' + formatMoney(price) + '</div>' +
'</li>' +
'<li>' +
'<div>Total</div>' +
'<div>' + totalAfterShipping(total, price) + '</div' +
'</li>' +
'</ul>' +
'</div>';
$('#cartOutput').html(cartItemHTML);
Here is the html where i am getting my data from:
<div class="delivery">
<div>Shipping method</div>
<div>Select the one you want</div>
<div class="delivery_options">
<label>Next day delivery
<input id="nextday" type="radio" name="radio" data-name="nextday" data-price="9000">
<span class="checkmark delivery1"></span>
<span class="delivery_price">R90</span>
</label>
<label>Standard delivery
<input id="standard" type="radio" name="radio" data-name="standard" data-price="3000">
<span class="checkmark delivery2"></span>
<span >R30</span>
</label>
<label>Personal pickup
<input id="pickup" type="radio" checked="checked" data-name="pickup" data-price="0" name="radio">
<span class="checkmark delivery3"></span>
<span >Free</span>
</label>
</div>
</div>
Here is the html where i am taking my data to:
<div class="col-lg-6 offset-lg-2">
<div class="cart_total">
<div>Cart total</div>
<div>Final info</div>
<div id="cartTotalOutput">
</div>
<div><input type="submit" class="button checkout_button"></div>
</div>
</div>
</div>
There's two issues here. Firstly add() is to add an element to a collection, not to attach an event handler. To do what you want use click() or on().
Secondly, price is only updated after the click event happens, yet your logic is attempting to read it immediately. To address this you need to put the console.log() line in that event handler. Try this:
var price = 0;
var $nextdayClass = $('.delivery1');
$nextdayClass.on('click', function() {
var nextday = $('#nextday').data('price');
price = nextday;
console.log(price);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="delivery1">Click me</button>
<div id="nextday" data-price="1.99">Next day: 1.99</div>
It's also worth noting that you should avoid the use of global variables where possible. A better pattern to use would be just retrieve the data attribute which holds the price where it's actually needed and remove the price variable completely.
It has nothing to do with scope.
Look at your code:
You get an element
You say that when you click the element price should be updated (well, you try to, you made a typo and called add instead of on)
You look at price
Presumably, at some point later, you click the element.
At this point price is updated.
You don't look at it again.
JavaScript does not time travel into the past and change price before you looked at it the first time.
The record of what the value was when you looked at it that is displayed in the console will not change.
If you want to log the value after you click on the element, you have to put the code that does the logging in the function that is called when you click on the element.
var price = 0;
var nextdayClass = $('.delivery1');
nextdayClass.on('click', function() {
var nextday = $('#nextday').data('price');
price = nextday; // The window object stuff is a waste of time
console.log("Clicked value", price);
});
console.log("Initial value", price);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="delivery1">5</button>
<span id=nextday data-price=5></span>
Try JQuery on() like this, also as I assume your element may be generated dynamically, try to bind the event handler to the body element/
var price = 0;
var nextdayClass = $('.delivery1');
$('body').on('click', nextdayClass, function() {
var nextday = $('#nextday').data('price');
window['price'] = nextday;
});
console.log(price); //Prints out 0

Reset name attribute array indexes, dynamically add remove rows

I have to post data via ajax and need the name attribute array indexes to reset.
For example:
1st row:
<select data-placeholder="Colours" class="colours chosen-select"
multiple tabindex="4" name="colours[0][]">
<option value="">Red</option>
<option value="">Orange</option>
</select>
2nd Row dynamically added:
<select data-placeholder="Colours" class="colours chosen-select"
multiple tabindex="4" name="colours[1][]">
<option value="">Red</option>
<option value="">Orange</option>
</select>
The name colours array must increment by 1 everytime I add, as well as reset the values when I remove.
I have looked around but not found any solution.
Here is what I have:
Adding:
var tbl = $("#service");
$("#addRowBtn").click(function () {
var count = $('#rowCount tr').length;
$("<tr>" +
"<td>" +
"<select data-placeholder=\"Colours\" class=\"colours chosen-select\"
multiple tabindex=\"4\"\ name=\"colours[" +
count +
"][]\">" +
"<option value=\"\">Red</option>" +
"<option value=\"\">Orange</option>" +
"</select></td>" +
"<td><i style=\"color:#d64830\" class=\"delRowBtn fa fa-minus-
circle\"></i></td></tr>").appendTo(tbl);
Deleting a row:
$(document.body).delegate(".delRowBtn", "click", function () {
$(this).closest("tr").remove();
});
I have added var count to increment the indexes, but I'm not able to reset the values when removing.
Please help!
You can try to cycle all select of your table and change the attribute "name" of each select everytime you delete an item.
$('#rowCount tr td select').each(function(idx, item){
$(item).attr("name", "colours[" + idx + "][]")
});
update
like suggest #ChayimFriedman the cool version of previous suggestion
$('#rowCount select').attr('name', function(idx) { return "colours[" + idx + "][]"; });

Appending a div (multiple times) in Jquery without cloning

I am still trying to work this out. Currently this is the way it looks, It works on JSFiddle but on my for it only clones once and the clone has data in it that when changed, changes the 1st item
I am trying to streamline my very large form to speed up the processes. I have a section that repeats multiple time that I want to reduce to having coded once with a button to add more if needed. The section cannot be cloned as each is separate and specific. Also note that they each need a unique identifier. As I have it not they ar "transectA", "transectB", etc. Below is a small snippet to give you an idea wof what I am working with. Each select actually has 12 options and there are 14 transects.
<div class="transect">
<select name="transectA" id="transectA">
<option value="">Transect A </option>
<option value = "RIGHT/SED-CORE">RIGHT/CORE</option>
<option value = "RIGHT/HOOP">RIGHT/HOOP</option>
<option value = "RIGHT/CHLPHL-1">RIGHT/TEMPLATE</option>
<option value = "RIGHT/NONE">RIGHT/NONE</option>
<option value = "CENTER/SED-CORE">CENTER/CORE</option>
<option value = "CENTER/HOOP">CENTER/HOOP</option>
<option value = "CENTER/CHLPHL-1">CENTER/TEMPLATE</option>
<option value = "CENTER/NONE">CENTER/NONE</option>
<option value = "LEFT/SED-CORE">LEFT/CORE</option>
<option value = "LEFT/HOOP">LEFT/HOOP</option>
<option value = "LEFT/CHLPHL-1">LEFT/TEMPLATE</option>
<option value = "LEFT/NONE">LEFT/NONE</option>
</select> </div>
I have attempted a couple of solutions (hide/show) & clone but neither give me a satisfactory result. All of the attempts I have tried with append seem to produce basically what the show/hide does.
<script>
$(document).ready(function() {
var $transect = $('.transect');
$transect.on('change', 'select', function() {
var $this = $(this),
$parent = $this.parent(),
$transects = $('.transect');
if($transects.length < 14 && !$parent.next('.transect').length) {
var ltr = String.fromCharCode(65 + $transects.length),
label = 'transect' + ltr;
$transect
.clone(true)
.find('select')
.attr('name', 'transect' + ltr)
.attr('id', 'transect' + ltr)
.find('option:eq(0)')
.text('Transect ' + ltr.toUpperCase())
.end()
.end()
.insertAfter($parent);
}
});
})
</script>
As always, your help will be greatly appreciated
Can anyone advise me why all of these solutions work in JSFiddle but not on my form. Even the script above works on the fiddle but only clones once on the form
you could do something like this:
var counter = 0
$('.add-new-button').click(function(){
$('#transectA').append('<option id="input ' + counter +'" value = "RIGHT/SED-CORE">RIGHT/CORE</option>');
counter++;
});
This will add a new option to #transectA. You can use this method to add form fields elsewhere as well. You can use the counter to make sure it has a unique ID or name or whatever. Good luck
You should be able to combine clone and some DOM manipulation to get the desired affect: http://jsfiddle.net/fjJfk/2/
But you'll likely need to make this example match your own markup/situation.
var $transect = $('._25');
$transect.on('change', 'select', function() {
var $this = $(this),
$parent = $this.parent(),
$transects = $('._25');
if($transects.length < 14 && !$parent.next('._25').length) {
var ltr = String.fromCharCode(65 + $transects.length);
$transect
.clone(true)
.find('select')
.attr('name', 'transect' + ltr)
.attr('id', 'transect' + ltr)
.find('option:eq(0)')
.text('Transect ' + ltr)
.end()
.end()
.insertAfter($parent);
}
});
You can use following;
HTML:
<div id="tempSelect" style="display:none">
<select name="transect" data-mini="true" id="transect">
<option value="">Transect_ </option>
<option value = "RIGHT/SED-CORE">RIGHT/CORE</option>
<option value = "RIGHT/HOOP">RIGHT/HOOP</option>
<option value = "RIGHT/CHLPHL-1">RIGHT/TEMPLATE</option>
<option value = "RIGHT/NONE">RIGHT/NONE</option>
</select>
</div
<fieldset>
<div class="_100">
</div>
</fieldset>
<input type="button" name="newSelect" id="newSelect" value="New"/>
JS:
$("#newSelect").on("click", function() {
var lastSelect = $("._100 select").last().attr("name");
if (lastSelect != undefined) {
var temp = lastSelect.split("_");
var id = parseInt(temp[1]) + 1;
} else {
var id = 0;
}
$("#tempSelect select").attr("name", "transect_" + id);
$("#tempSelect select").attr("id", "transect_" + id);
$("#tempSelect select option:first").text("Transect_" + id);
$("._100").append($("#tempSelect").html());
});
Here is working demo: jsfiddle

Remove item from second dropdown based on selection in First using Javascript

I have four dropdown, and I am manually filling them.
Now I want to add a javacsript that when I select first dropdown option, then in the second third fourth dropdowns, that item or option can be removed.
And same flow goes for second third and fourth and so on.
I am giving my code but till now, it is not working fine.
I am only tring for the first ladder, that is when option in first is selected then item removed from second, third and fourth dropdowns.
function RemoveItems(){
var List1 = document.getElementById("ddlSortField");
var sortList1 = List1.options[List1.selectedIndex].text;
var List2 = document.getElementById("ddlSortField2");
var sortList2 = List2.options[List2.selectedIndex].text;
List2.options.remove(sortList1);
var List3 = document.getElementById("ddlSortField3");
var sortList3 = List3.options[List3.selectedIndex].text;
List3.options.remove(sortList2);
var List4 = document.getElementById("ddlSortField4");
var sortList4 = List4.options[List4.selectedIndex].text;
List4.options.remove(sortList3);
}
In your code:
> function RemoveItems(){
Variable names starting with a capital letter are, by convention, reserved for constructors, so:
function removeItems() {
> var List1 = document.getElementById("ddlSortField");
> var sortList1 = List1.options[List1.selectedIndex].text;
So sortList1 will be a string.
> var List2 = document.getElementById("ddlSortField2");
> var sortList2 = List2.options[List2.selectedIndex].text;
> List2.options.remove(sortList1);
The remove method of the options collection takes a single parameter that is an index of one of the options. You have not shown what the value of sortList1 nor how many options List2 has. Note that the options collection is live, so if you remove an option, the indexes of other options may be adjusted so that they are contiguous from 0 to options.length - 1.
You can use such code : jsFiddle.
Basically, you first bind the change event to each list and when you change the value you hide these elements in all lists after...
I've made a slightly different one than #Muhammad Omair's, this one is a bit more dynamic. Note that this is jQuery
var removeSelection = function(select) {
$('select').filter(':not(#' + select.attr('id') + ')').each(function() {
var index = select.find(':selected').index();
$(this).find('option:eq(' + index + ')').remove();
});
};
$(function() {
$('select').change(function() {
removeSelection($(this));
});
});
And here's a jsfiddle of it http://jsfiddle.net/cA3F9/
Use jQuery to remove option
$(document).ready(function(){
$('#ddlSortField').change(function(){
var index = $("#ddlSortField option:selected").val();
$('#ddlSortField2 option:eq(' + index + ')').remove();
$('#ddlSortField3 option:eq(' + index + ')').remove();
$('#ddlSortField4 option:eq(' + index + ')').remove();
});
});
Note in your html your option value must be same like this:
<select id="ddlSortField">
<option value="1">test1</option>
<option value="2">test2</option>
<option value="3">test3</option>
</select>
<select id="ddlSortField1">
<option value="1">test1</option>
<option value="2">test2</option>
<option value="3">test3</option>
</select>

Getting a SelectList obejct from a ListBox and placing into an HTML Selection List

Say I have a ListBox populated with a name value pair SelectList(myUsers, "Key", "Value"):
#Html.ListBox("ListReviewers", (SelectList)ViewBag.ListOFReviewers, new { style = "width:120px;" })
I want to double click an option in this ListBox, and place it in a SelectionList like below:
<div class="selectedEmployees">
<select class="selectionList" multiple="multiple" name="AssignedReviewer" style="width:120px;">
<!--x.UserID, x.FirstName + " " + x.LastName) -->
<option value=""></option>
</select>
</div>
Once this collection is placed in the above, I want to store all the values in another SelectionList Collection for later use.
Here is the start of my jQuery code:
<script type="text/javascript">
$('#ListReviewers').dblclick(function (i, selected) {
//double click on this value of listbox of type SelectList(myUsers, "Key", "Value")
//store this value and text
var value = $(this).val;
//var empName = $(this).data[0];
var empName = $(selected).text();
alert(empName);
//append an option element <option value=""></option>
$('.selectionList').append('<option id="' + value + '">' + empName + '</option>');
});
I can get the value of the dblclicked collection object, but not the text of the collection object. Is there a better way to do this?
Try attaching your event to the option within the select itself. You can then use this to access it's properties.
$('#ListReviewers option').dblclick(function () {
var value = $(this).val();
var empName = $(this).text();
$('.selectionList').append('<option id="' + value + '">' + empName + '</option>');
});
Alternatively, you can use clone() and append() to move the option from one select to the other. This will save you having to worry about duplicate options being appended.
$('#ListReviewers option').dblclick(function () {
var $newOptions = $(this).clone(false);
$(this).remove();
$('.selectionList').append($newOption);
});

Categories

Resources