Reset variable values each time a jQuery function runs - javascript

I want to run my function when the page first loads, and again when certain elements are clicked. Each time this function is ran I need it to update the variables, but as it sits right now it is keeping the values that it found the first time the function ran.
I tried searching for this issue and found people saying to just set it to null, or undefined. So I tried doing this by adding var price = null;, var x = null;, etc. at the end of the function. That didn't do anything. So I tried adding an if statement at the top to see if price has a value greater than 0, and then changing every variable to null if it is. This didn't change anything. Now I'm not sure if I need to just re-write the entire thing, or maybe there is some other detail that I am missing?
Thanks in advance for your help.
jQuery(document).ready(function(){
var bessie = function(){
//remove or reset value of variables for next time function runs
if(price > 0){
var qtyCode = null;
var qty = null;
var price = null;
var total = null;
var newContent = null;
};
//Pull html code for plus/minus qty selector
var qtyCode = jQuery('.qtyswitcher-qty').html();
//Get value of qty that is currently selected
var qty = jQuery('#qtyswitcher-qty').val();
//Pull the current price and change the string to a number
var price = jQuery('.price').first().text().replace(/[^0-9\.]+/g,"");
//multiply price by qty to get the total for the users current selection
var total = price * qty;
//New html that will be inserted into the page
var newContent = '<p class="multiply">' + '$' + price + '/ea</p>' + '<p class="multiply2">x</p>' + '<div id="qty">' + qtyCode + '</div>' + '<p class="multiply3">=</p> <p class="multiply">' + '$' + total.toFixed(2) + '</p>';
//New html being inserted
jQuery(".qtyswitcher-qty").replaceWith(newContent);
};
bessie();
jQuery('.switcher-label').click(bessie);
jQuery('#qtyswitcher-oneless').click(bessie);
jQuery('#qtyswitcher-onemore').click(bessie);
});
Moved some things around and added some new code based on Data's comments. I'm not sure I did this correctly. I had also tried it with and without the parenthesis as was mentioned below. It's still staying as $9.00 even though you can see that the .price element is changing on the page when the items are clicked.
Link to page with the html I am messing with
<script type="text/javascript">
var bessie = function(){
//Pull html code for plus/minus qty selector
var qtyCode = jQuery('.qtyswitcher-qty').html();
//Get value of qty that is currently selected
var qty = jQuery('#qtyswitcher-qty').val();
//Pull the current price and change the string to a number
var price = jQuery('.price').first().text().replace(/[^0-9\.]+/g,"");
//multiply price by qty to get the total for the users current selection
var total = price * qty;
//New html that will be inserted into the page
var newContent = '<p class="multiply">' + '$' + price + '/ea</p>' + '<p class="multiply2">x</p>' + '<div id="qty">' + qtyCode + '</div>' + '<p class="multiply3">=</p> <p class="multiply">' + '$' + total.toFixed(2) + '</p>';
//New html being inserted
jQuery(".qtyswitcher-qty").replaceWith(newContent);
};
bessie();
$('.switcher-label, #qtyswitcher-oneless, #qtyswitcher-onemore' ).on('dblclick click', function(e) {
bessie(e);
e.stopImmediatePropagation();
});
</script>
Found the problem now, but still working on a complete solution. The .replaceWith(); was replacing the html in a way that made it not able to display updated info. The code below is working, but the problem now is that I need to find a way replace the html each time without breaking it. The way it sits now it is adding more html to the page when an element is clicked. My code is still a bit messy.
<script type="text/javascript">
jQuery(document).ready(function() {
var bessie = function(){
//Pull html code for plus/minus qty selector
var qtyCode = jQuery('.qtyswitcher-qty').html();
//Get value of qty that is currently selected
var qty = jQuery('#qtyswitcher-qty').val();
//Pull the current price and change the string to a number
var price = jQuery('.price').first().text().replace(/[^0-9\.]+/g,"");
//multiply price by qty to get the total for the users current selection
var total = price * qty;
//New html being inserted
jQuery(".qtyswitcher-add-to-cart-box").append('<p class="multiply">' + '$' + price + '/ea</p>' + '<p class="multiply2">x</p>' + '<div id="qty">');
jQuery(".qtyswitcher-qty").append('</div>' + '<p class="multiply3">=</p> <p class="multiply">' + '$' + total.toFixed(2) + '</p>');
};
bessie();
jQuery('.switcher-label').click(bessie);
jQuery('.input-box').click(bessie);
jQuery('#qtyswitcher-oneless').click(bessie);
jQuery('#qtyswitcher-onemore').click(bessie);
});
</script>

It's easier to separate html from javascript, so I recommend using handlebars. You pass an object and it returns html you can then use in jQuery. Notice the html string uses back-ticks to concatenate multi-line strings.
<script>
var html = `<p class="multiply">${{price}}/ea</p>
<p class="multiply2">x</p><div id="qty">{{qtyCode}}</div>
<p class="multiply3">=</p><p class="multiply">'$'{{total}}</p>`;
function bessie(){
var obj = { 'qtyCode' : $('.qtyswitcher-qty').html(),
'qty' : $('#qtyswitcher-qty').val(),
'price' : $('.price').first().text().replace(/[^0-9\.]+/g,"") };
obj.total = obj.price * obj.qty;
var template = handlebars.compile(html),
compiled = template(obj);
$(".qtyswitcher-qty").replaceWith(compiled);
};
function addListeners(){
$('.switcher-label').click(bessie());
$('#qtyswitcher-oneless').click(bessie());
$('#qtyswitcher-onemore').click(bessie());
}
$(document).ready( addListeners(); bessie(); );
</script>

Fixed it! Used insertBefore() and insertAfter() to add the html content where I wanted it. Also added a div with the class remove me that will have .remove(); used on it each time an element is clicked.
<script type="text/javascript">
jQuery(document).ready(function() {
var bessie = function(){
//Pull html code for plus/minus qty selector
var qtyCode = jQuery('.qtyswitcher-qty').html();
//Get value of qty that is currently selected
var qty = jQuery('#qtyswitcher-qty').val();
//Pull the current price and change the string to a number
var price = jQuery('.price').first().text().replace(/[^0-9\.]+/g,"");
//multiply price by qty to get the total for the users current selection
var total = price * qty;
//New html being inserted
jQuery( '<div class="removeMe"><p class="multiply">' + '$' + price + '/ea</p>' + '<p class="multiply2">x</p>' + '</div><div id="qty">' ).insertBefore( '.qtyswitcher-qty');
jQuery( '</div>' + '<div class="removeMe"><p class="multiply3">=</p> <p class="multiply">' + '$' + total.toFixed(2) + '</p></div>' ).insertAfter( '.qtyswitcher-qty' );
};
bessie();
jQuery('.switcher-label, .input-box, #qtyswitcher-oneless, #qtyswitcher-onemore' ).click(function() {
jQuery( '.removeMe' ).remove();
bessie();
});
});
</script>

Related

Append contents of each div to textarea

I have a list of divs created server-side, each with a price, quantity (entered by the user) and name. I've managed to use jQuery to calculate the total of each and add those up.
What I'd like to do now is to list the name, quantity and total of each item that has a value in my textarea, on a per-row basis.
So far I've got the following (the append part of which doesn't currently work):
$(document).ready(function () {
$(".product-row input").change(multInputs);
function multInputs() {
var mult = 0;
// for each row:
$("div.product-row").each(function () {
// get the values from this row:
var $price = $('.price', this).html();
var $quantity = $('.quantity', this).val();
var $total = ($price * 1) * ($quantity * 1);
// set total for the row
$('.multTotal',this).text($total);
mult += $total;
$('#textarea',this).append($name).append($total);
});
$("#total").html(mult);
}
});
If I can get this worked out, I'm pretty sure I can work out how to add the grand total and clear the textarea each time something is changed (I'm not looking for someone to do all the work).
Any feedback as to why my textarea isn't populating would be very much appreciated.
Edit: The solution, really well explained below by braks has resulted in the following (working!) code:
$(document).ready(function () {
$(".product-row input").change(multInputs);
function multInputs() {
var mult = 0;
// for each row:
$("div.product-row").each(function () {
// get the values from this row:
var price = $('.price', this).html();
var quantity = $('.quantity', this).val();
var name = $('.name', this).html();
var total = (price * 1) * (quantity * 1);
// set total for the row
$('.multTotal',this).text(total);
mult += total;
$('#textarea').val($('#textarea').val() + ' ' + name + ' ' + total);
});
$("#total").html(mult);
}
});
$(textarea).append(txt) doesn't work like you think. When a page is loaded the text nodes inside the textarea are set the value of that form field. After that, the text nodes and the value can be disconnected. As you type in the field, the value changes, but the text nodes inside it on the DOM do not. Then you change the text nodes with the append() and the browser erases the value because it knows the text nodes inside the tag have changed.
So you want to set the value, you don't want to append. Use jQuery's val() method for this.
You have to use something like $('#textarea').val($('#textarea').val() + ' ' + $name + ' ' + $total);
Except I'm not sure why you put $ in your variables, mix up with PHP ?

How to style dynamically generated Select2 dropdowns after the page has loaded?

I am using Select2 for dropdown styling from http://ivaynberg.github.io/select2/ .
I have several dropdowns on the page which are styled correctly using the following:
<script>
$(document).ready(function() {
$("#dropdown1").select2();
$("#dropdown2").select2();
});
</script>
Now, I have another option on the page where it allows the user to add as many dropdowns as they want for additional options, the following way:
<img src="images/add.png" title="Add Row" border="0" onclick="addRowToCountryPrice('',''); return false;">
<input type="hidden" name="TotalLinesCountry" id="TotalLinesCountry">
<script>
var arr = new Array();
var ind=0;
function showCountryDrop(name1,sel, param){
var dval="";
dval = "<select name=\"" + name1 + "\" id=\"" + name1 + "\" class=\"countriesclass\">";
dval += "<option value=\"\">Select Country</option>\r\n";
selVal = (sel==0001) ? "selected=\"selected\"" : " " ;
dval += "<option value=\"0001\" " + selVal + ">United Kingdom</option>";
selVal = (sel==0002) ? "selected=\"selected\"" : " " ;
dval += "<option value=\"0002\" " + selVal + ">United States</option>";
selVal = (sel==0003) ? "selected=\"selected\"" : " " ;
dval += "<option value=\"0003\" " + selVal + ">Albania</option>";
selVal = (sel==0004) ? "selected=\"selected\"" : " " ;
dval += "<option value=\"0004\" " + selVal + ">Algeria</option>";
dval +="</select>";
return dval;
}
function addRowToCountryPrice(country,price) {
var tbl = document.getElementById("tblCountryCurrency");
var lastRow = tbl.rows.length;
var iteration = lastRow;
var row = tbl.insertRow(lastRow);
var cellVal = "";
var cellLeft;
var i=0;
arr[ind] = (iteration+1);
cellLeft = row.insertCell(i++);
cellLeft.innerHTML = showCountryDrop("countryDrop_" + ind,country);
cellLeft = row.insertCell(i++);
var price = (price!=0) ? price : "0.00";
cellLeft.innerHTML = "<input type=\"text\" name=\"countryPrice_" + ind + "\" id=\"countryPrice_" + iteration + "\" value = \"" + price + "\" size=\"8\">";
cellLeft = row.insertCell(i++);
cellLeft.innerHTML = "<img src=\"images/delete.png\" title=\"Delete Row\" border=\"0\" onclick=\" removeRowFromTable(" + ind + "); return false;\">";
document.getElementById("TotalLinesCountry").value = (parseInt(ind)+1);
ind++;
}
function removeRowFromTable(src)
{
var tbl = document.getElementById("tblCountryCurrency");
var lastRow = tbl.rows.length;
if (arr[src]!="") tbl.deleteRow((arr[src]-1));
arr[src]="";
var counter = 1;
for( i=0; i<arr.length; i++) {
if (arr[i]!="") {
arr[i]= counter;
counter++;
}
}
return false;
}
</script>
While it generates the dropdowns correctly, they are not styled through the class "countriesclass", even if I do a:
$(".countriesclass").select2();
I also tried
dval +="</select>";
$(".countriesclass").select2();
return dval;
And that seems to be PARTIALLY working in a strange way. When I create the first dropdown, it doesn't get styled. When I create another second dropdown, then the first one gets styled but the second one doesn't. It then doesn't let me create further ones and shows an error.
Any ideas how I could get this working?
UPDATE: jsFiddle http://jsfiddle.net/y6af098z/2/
Your call to $('.countriesclass') goes off when the document is ready. But the select has not been added to the document yet, then. So no elements are found.
You should look up the added select after the user has clicked on the plus and you've added the select to the dom.
$('#plus').on('click', function () {
$tr = addRowToCountryPrice('Algeria', 0);
$('.countriesclass', $tr).select2();
});
The second argument $tr tells jquery only to look in the recently added table row, so that you only select the newly added select which is a child of the newly added tr. Not the selects in the other rows.
Like #dreamweiver already noted, you should make better use of jquery when creating the dom elements. That's what jquery is good at. I've updated the jsfiddle to show how you can create the select and table row the jquery way.
DEMO
Instead of using getelementbyId use getelementbyClass and give each dropdown a class, you can only have one getelementbyid.
Hope this helps. if you want i could send you the code for what you require?
The select2 when called was not able to find the dropdown list boxes,because they were added dynamically and hence the those were not visible for the jQuery class selector $(".countriesclass").select2();.
This type of behaviour can be overcome by referencing the selector from the document element, rather than referring the element directly like above. so the new selector should be like this
$(document).find("select.countriesclass").select2();
Also I have done few tunings in your code.
Live demo:
http://jsfiddle.net/dreamweiver/y6af098z/8/
Note: one more thing, when using jQuery lib make sure you make the most of it, don't use raw JS code instead use the jQuery equivalent syntax for the same, which would be simple and easy to use.

How to Create List and Display List in Textarea

I'm developing a food order system. I want show my order list in a textarea. Right now I can make list in a div's content. I also want my result price to be rounded at two decimal place like if you enter 2, it'll be formatted to 2.00.
My full code is a bit long.
This is a sample of the JavaScript I use :
function addNewItem() {
price = 4.50;
result += price;
appendElement("container", "element" + price, "Cappucino Ice Blended " + price + "[Remove]");
document.getElementById('sumOrder').value = result;
}
The full code in a fiddle
To create new lines in the textarea, so that it looks like a list, you can delimit your orders with "\n".
Example: http://jsfiddle.net/U58gT/
<textarea id="orders" rows="10"></textarea>
<br /><br /><br />
<input id="new-order" type="text"><button>add order</button>
$('button').click(function() {
var new_order = $('#new-order').val();
$('#orders').append(new_order + "\n");
});
Thanks for reply but I using other method. I already can make list in text area. Now i got the problem to remove it when i click remove link. In DIV's i can remove properly but the textarea not remove. i using this code for make list in textarea.
This is a sample of the JavaScript I use :
var result =0.00;
function addtxt(input) {
price = 4.50;
result += price;
var obj=document.getElementById(input)
var txt=document.createTextNode("Cappucino Ice Blended "+ price+"\n")
obj.appendChild(txt)
addNewItem();}
function addNewItem()
{
appendElement("container", "element" + price, "Cappucino Ice Blended " + price + "[Remove]");
document.getElementById('sumOrder').value = result;
}
function removeItem(price)
{
result -= price;
removeElement("container", "element" + price);
document.getElementById('sumOrder').value = result;
}
function removeElement(parentId, elementId)
{
var parentElement = document.getElementById(parentId);
var childElement = document.getElementById(elementId);
parentElement.removeChild(childElement);
}
function appendElement(containerId, newElementId, newElementContent)
{
var newElement=document.createElement("div");
newElement.setAttribute("id", newElementId);
newElement.innerHTML=newElementContent;
var container = document.getElementById(containerId);
container.appendChild(newElement, container);
}
The full code in a fiddle

Jquery reading input field that was created from JSON loop

I cannot figure out for the life of me why this will not work. I am trying to pull the value of a textfield that was created with a loop from a json file.
In this code, at the very bottom I just do a simple click(function() {alert()} just to see if I can pull a value and its returning undefined. But if I remove '#name' and put in 'input' it captures it, but only for the first of several input fields.
Any help is really appreciated
JSON
{
"Controls": [{
"Button":[{ "Name":"Button", "x": "1","y": "2","width": "3","height": "4","Transition":"" }],
"Image":[{"x": "5","y": "6","width": "7","height": "8"}],
"TextField":[{"x": "9","y": "10","width": "11","height": "12","Rows":""}]
}]
}
The Code(there is soome getJSON stuff above this)
//Slide In Attributes Panel Based on Selected Object
$(document).on('click', '#code li', function () {
var index = $('#code li').index(this);
var selected = $(this).text();
switch (selected) {
case selected:
$('#options').hide();
hidePanels();
$('#temp').remove();
$('#objectAttributes').show("slide", 200);
break;
//If it does work show what variable is being used
default:
alert(selected);
break;
}
//Shows Selected LI Index
$('#codeIndex').text("That was div index #" + index);
//Pull list of Attributes for selected Object
$.getJSON('controls.json', function (data) {
//Build Attributes List
var attributeList = '<div id="temp">';
//Target based on selected object
var target = selected;
attributeList += '<div>' + target + '<div>';
$.each(data.Controls[0][target][0], function (kk, vv) {
attributeList += '<div style="float:right">' + kk + ':' + '<input type="text" id='+ kk + '>' + '</input>' + '</div>';
});
attributeList += '</div></div>';
attributeList += '</div>';
$('#objectAttributes').append(attributeList);
$('#temp').append('<div id="editIndex">'+"Modifying index" + " " +index+'</div>');
$(document).on('click', '#saveAttributes', function () {
var $x = $('#name').val();
alert($x);
})
});
});
Ok, so after a little hacking around with a jsfiddle the answer turned out to be a lot simpler than I first thought. Ever since HTML 4.01 class names and IDs have been case sensitive (reference), which means that your selector $('#name') wasn't matching the JSON Name.
So a simple change, such as in this simplified jsfiddle seems to work as desired. Hopefully this helps!

Selecting textareas within div tags

feel like im coming here way too often to ask questions but yet again I am stuck. I am attempting to select a textarea and allow myself to edit the text in another textarea, which works fine using textboxs but not with textareas. Every time I click on the div container I am getting an undefined result when looking for the textarea. Below is the code.
jQuery
$(".textAreaContainer").live('click','div', function(){
var divID = this.id;
if ( divID !== "" ){
var lastChar = divID.substr(divID.length - 1);
var t = $('#' + divID ).find(':input');
alert(t.attr('id'));
t = t.clone(false);
t.attr('data-related-field-id', t.attr('id'));
t.attr('id', t.attr('id') + '_Add');
t.attr('data-add-field', 'true');
var text = document.getElementById(divID).innerHTML;
//var textboxId = $('div.textAreaContainer').find('input[type="textArea"]')[lastChar].id;
$('div#placeholder input[type="button"]').hide();
var text = "<p>Please fill out what " + t.attr('id') +" Textarea shall contain</p>";
if ( $('#' + t.attr('id')).length == 0 ) {
$('div#placeholder').html(t);
$('div#placeholder').prepend(text);
}
}
else{
}
});
t.attr('id') should be returning textbox1(or similar) but instead just returns undefined.
I have tried .find(':textarea'),.find('textarea'),.find(text,textArea),.find(':input') and quite a few others that I have found through google but all of them return undefined and I have no idea why. A demo can be found here, http://jsfiddle.net/xYwaw/. Thanks in advance for any help guys, it is appreciated.
EDIT: Below is the code for a very similar example I am using. This does what I want to do but with textboxs instead of textareas.
$('#textAdd').live('click',function() {
var newdiv = document.createElement('div');
newdiv.innerHTML = "Textbox " + textBoxCounter + " <br><div id='container" + counter + "' class='container'><li><input type='text' id='textBox" + textBoxCounter +"' name='textBox" + textBoxCounter + "'></li></div></br>";
document.getElementById("identifier").appendChild(newdiv);
textBoxCounter++
counter++;
});
$(".container").live('click','div', function(){
var divID = this.id;
if ( divID !== "" ){
var lastChar = divID.substr(divID.length - 1);
var t = $('#' + divID).find('input');
alert(divID);
t = t.clone(false);
t.attr('data-related-field-id', t.attr('id'));
alert(t.attr('id'));
t.attr('id', t.attr('id') + '_Add');
t.attr('data-add-field', 'true');
var text = document.getElementById(divID).innerHTML;
// var textboxId = $('div.container').find('input[type="text"]')[lastChar].id;
$('div#placeholder input[type="button"]').hide();
var text = "<p>Please fill out what " + t.attr('id') +" textbox shall contain</p>";
if ( $('#' + t.attr('id')).length == 0 ) {
$('div#placeholder').html(t);
$('div#placeholder').prepend(text);
}
}
else{
}
});
First up remove the second parameter, 'div', from the first line:
$(".textAreaContainer").live('click','div', function(){
...to make it:
$(".textAreaContainer").live('click', function(){
Then change:
var t = $('#' + divID ).find(':input');
...to:
var t = $(this).find(':input');
Because you already know that this is the container so there's no need to select it again by id. Also the id attributes that you're assigning to your textarea containers have a space in them, which is invalid and results in your original code trying to select the element with '#textAreaContainer 0' which actually looks for a 0 tag that is a descendant of #textAreaContainer. So fixing the code that creates the elements to remove that space in the id is both a good idea in general and an alternative way of fixing this problem.

Categories

Resources