JQuery ID + count - javascript

When I dynamically create checkbox and div, I want to have different id for each of them (like id_1, id_2...).
The first value of my array is erased by the next value.
Currently, I create checkbox for each value I have in my array:
var containerCheckbox = $('#listCheckboxCategories');
// var listCheckboxCategories = $('#listCheckboxCategories');
var CheckboxCreate = '<input id="catCheckbox" type="checkbox" name="categoriesCheckbox" required/>';
var categoriesName = '<span id="catName"/>';
if (tileConfig.isThereFilterRadios == "Yes" && res !== undefined) {
$('#ShowCategories').show();
$('#containerCategories').show();
$.each(res.list, function(index, cat) {
//ToDo: inserer cat.name dans le span
// categoriesName.html(cat.name)
containerCheckbox.append(CheckboxCreate, categoriesName);
$("#catName").html(cat.name);
});
}
Can someone help me ?

You could create a function to return the checkbox element, that way you could pass a variable into the function (eg index) to add to the html to make each id unique
for example
createCheckbox = function (index) {
return '<input id="catCheckbox_' + index + '" type="checkbox" name="categoriesCheckbox" required/>';
}
var containerCheckbox = $('#listCheckboxCategories');
var categoriesName = '<span id="catName"/>';
if (tileConfig.isThereFilterRadios == "Yes" && res !== undefined) {
$('#ShowCategories').show();
$('#containerCategories').show();
$.each(res.list, function(index, cat) {
containerCheckbox.append(createCheckbox(index), categoriesName);
$("#catName").html(cat.name);
});
}

Related

Different output for blank input in search function

I've written a small function for a search bar. Currently if the input doesn't match anything in my array, the function returns the last object in said array (which i made to be empty). I want to change it so that if the input is blank, the function returns "No Result" or something like that. Any ideas why this code isn't working as intended?
let websitePages =
'{"website_pages":[' +
'{"name":"Hamza", "path":"/hamza/"},' +
'{"name":"Jakub", "path":"/jakub/"},' +
'{"name":"Kevin", "path":"/kevin/"},' +
'{"name":"Sreeja", "path":"/sreeja/"},' +
'{"name":"Tristan", "path":"/tristan/"},' +
'{"name":"Math", "path":"/math/"},' +
'{"name":"History", "path":"/history/"},' +
'{"name":"Science", "path":"/sci/"},' +
'{"name":"Literature", "path":"/lit/"},' +
'{"name":"Periodic Table", "path":"/periodictable/"},' +
'{"name":"API Collection", "path":"/api_collection/"},' +
'{"name":"CRUD", "path":"/crud/"},' +
'{"name":"Async CRUD", "path":"/crud_api/"},' +
'{"name":"Database Search", "path":"/crud/search/"},' +
'{"name":"Search (Database)", "path":"/crud/search/"},' +
'{"name":"", "path":"//"}]}'; // this object is empty in case the user inputs a blank, so that the previous result is removed and no link is returned
function SearchMain() {
list = JSON.parse(websitePages);
input = document.getElementById("SearchInput");
filter = input.value.toUpperCase(); // the user's input is changed to uppercase so that the search is not case-sensitive
for (i = 0; i < websitePages.length; i++) {
// this section goes through the items in my array and checks if the user's input is the same as any object name
if (
filter ===
list.website_pages[i].name.toUpperCase().substring(0, filter.length)
) {
//using substrings allows users to only input part of the page name instead of the whole thing
link = list.website_pages[i].path;
document.getElementById("searchResult").innerHTML =
list.website_pages[i].name;
document.getElementById("searchResult").href = link;
} else if (filter === null) {
document.getElementById("searchResult").innerHTML = "No Results";
document.getElementById("searchResult").href = "";
}
}
}
For loop condition should be i < list.website_pages.length, also you should handle two error scenarios. One is input is empty and the search didnot find any valid match. I have updated them in the below fiddle.
Working Fiddle
let websitePages = '{"website_pages":[' +
'{"name":"Hamza", "path":"/hamza/"},' +
'{"name":"Jakub", "path":"/jakub/"},' +
'{"name":"Kevin", "path":"/kevin/"},' +
'{"name":"Sreeja", "path":"/sreeja/"},' +
'{"name":"Tristan", "path":"/tristan/"},' +
'{"name":"Math", "path":"/math/"},' +
'{"name":"History", "path":"/history/"},' +
'{"name":"Science", "path":"/sci/"},' +
'{"name":"Literature", "path":"/lit/"},' +
'{"name":"Periodic Table", "path":"/periodictable/"},' +
'{"name":"API Collection", "path":"/api_collection/"},' +
'{"name":"CRUD", "path":"/crud/"},' +
'{"name":"Async CRUD", "path":"/crud_api/"},' +
'{"name":"Database Search", "path":"/crud/search/"},' +
'{"name":"Search (Database)", "path":"/crud/search/"},' +
'{"name":"", "path":"//"}]}'; // this object is empty in case the user inputs a blank, so that the previous result is removed and no link is returned
function SearchMain() {
list = JSON.parse(websitePages);
input = document.getElementById('SearchInput');
filter = input.value.toUpperCase(); // the user's input is changed to uppercase so that the search is not case-sensitive
let isFound = false;
for (i = 0; i < list.website_pages.length; i++) { // this section goes through the items in my array and checks if the user's input is the same as any object name
if (filter === list.website_pages[i].name.toUpperCase().substring(0, filter.length)) { //using substrings allows users to only input part of the page name instead of the whole thing
link = list.website_pages[i].path;
document.getElementById('searchResult').innerHTML = list.website_pages[i].name;
document.getElementById('searchResult').href = link;
isFound = true;
}
}
if (!filter || !isFound) {
document.getElementById('searchResult').innerHTML = "No Results"
document.getElementById('searchResult').href = ""
}
}
<input type="text" id="SearchInput" />
<button onclick="SearchMain()">SearchMain</button>
<a id="searchResult"></a>
Simplified solution.
Avoid using for loop and make use of Array.find to find the matching node from the list.
Working Fiddle
let websitePages = '{"website_pages":[' +
'{"name":"Hamza", "path":"/hamza/"},' +
'{"name":"Jakub", "path":"/jakub/"},' +
'{"name":"Kevin", "path":"/kevin/"},' +
'{"name":"Sreeja", "path":"/sreeja/"},' +
'{"name":"Tristan", "path":"/tristan/"},' +
'{"name":"Math", "path":"/math/"},' +
'{"name":"History", "path":"/history/"},' +
'{"name":"Science", "path":"/sci/"},' +
'{"name":"Literature", "path":"/lit/"},' +
'{"name":"Periodic Table", "path":"/periodictable/"},' +
'{"name":"API Collection", "path":"/api_collection/"},' +
'{"name":"CRUD", "path":"/crud/"},' +
'{"name":"Async CRUD", "path":"/crud_api/"},' +
'{"name":"Database Search", "path":"/crud/search/"},' +
'{"name":"Search (Database)", "path":"/crud/search/"},' +
'{"name":"", "path":"//"}]}'; // this object is empty in case the user inputs a blank, so that the previous result is removed and no link is returned
function SearchMain() {
list = JSON.parse(websitePages);
input = document.getElementById('SearchInput');
filter = input.value.toUpperCase(); // the user's input is changed to uppercase so that the search is not case-sensitive
const matchingNode = filter ? list.website_pages.find(node => filter === node.name.toUpperCase().substring(0, filter.length)) : null;
if (matchingNode) {
document.getElementById('searchResult').innerHTML = matchingNode.name;
document.getElementById('searchResult').href = matchingNode.path;
}
else {
document.getElementById('searchResult').innerHTML = "No Results"
document.getElementById('searchResult').href = ""
}
}
<input type="text" id="SearchInput" />
<button onclick="SearchMain()">SearchMain</button>
<a id="searchResult"></a>

How to add more items to local storage?

I am just starting with programming and I am playing around with this todo list. Now I want to add my todo items to local storage.
But everytime I add a new item to the list I overwrite the one and only to do item.
How do I solve this?
Here is the code:
$(document).ready(function() {
var data = JSON.parse(localStorage.getItem("todoData"));
for (var i = 0; i < localStorage.length; i++) {
$('#thingsTodo').append('<div class="section">' +
'<li id="listItem" class="blue-text text-darken-2 tooltip">' + data + '<span class="tooltiptext">Click to edit</span></li>' +
'<i class="small material-icons deleteThisItem">delete</i>' +
'<div class="divider"></div>');
}
$('#addItem').on('click', addItemToList);
$('#thingsTodo').on('click', '.deleteThisItem', deleteItem);
$('#thingsTodo').on('click', '#listItem', editItem);
function addItemToList() {
var newItem = {
value: $('#inputField').val()
};
if (newItem.value !== '') {
localStorage.setItem("todoData", JSON.stringify(newItem.value));
$('#thingsTodo').append('<div class="section">' +
'<li id="listItem" class="blue-text text-darken-2 tooltip">' + newItem.value + '<span class="tooltiptext">Click to edit</span></li>' +
'<i class="small material-icons deleteThisItem">delete</i>' +
'<div class="divider"></div>');
$('#inputField').val("");
} else {
alert("Please make sure you enter something before clicking the button");
}
}
function deleteItem() {
$(this).closest('.section').remove();
$(this).closest('.divider').remove();
}
function editItem() {
var newTodoInput = {
newValue: prompt("Please edit your todo item")
};
if (typeof newTodoInput.newValue !== 'object') {
if (newTodoInput.newValue !== "") {
$(this).replaceWith('<li id="listItem" class="blue-text text-darken-2 tooltip">' + newTodoInput.newValue + '<span class="tooltiptext">Click to edit</span></li>');
}
} else {
alert("Please make sure you enter something before clicking the button");
}
}
});
If possible please also show me how to save it when I edit a list item.
When you create a new to do item you could push that item to a global array then add at that array to your local store like this.
var items = [];
function addItemToList (){
var input = $('#inputField').val()
items.push(input);
if(input){
localStorage.setItem("todoData", JSON.stringify(items));
$('#thingsTodo').append('<div class="section">'+
'<li id="listItem" class="blue-text text-darken-2 tooltip">' + item + '<span class="tooltiptext">Click to edit</span></li>'+
'<i class="small material-icons deleteThisItem">delete</i>'+
'<div class="divider"></div>');
$('#inputField').val("");
}else{
alert("Please make sure you enter something before clicking the button");
}
}
Use localStorage.setObj(key, value) to save an array or object and localStorage.getObj(key) to retrieve it like this
$(document).ready(function() {
var storedItems = JSON.parse(localStorage.getItem("toDoData"));
for(var i = 0; i < storedItems.length; i++) {
$('#thingsTodo').append('<div class="section">'+
'<li id="listItem" class="blue-text text-darken-2 tooltip">' + storedItems[i] + '<span class="tooltiptext">Click to edit</span></li>'+
'<i class="small material-icons deleteThisItem">delete</i>'+
'<div class="divider"></div>');
}
});
In youraddItemToList function you are using always the same key for all question. It's normal behavior that it overrides the existing one. You must either store your todo items in an array under the same key or have different keys for each item.
Simplified code for array.
var initialTodos = [];
localStorage.setItem('todoData', JSON.stringify(initialTodos );
// add item
function addItem(item) {
var todos = getTodos();
todos.push(item);
localStorage.setItem('todoData', JSON.stringify(todos));
}
// remove get data
function getTodos() {
return JSON.parse(localStorage.getItem('todoData'));
}
// remove item
function removeItem(item) {
var todos = getTodos();
var index = todosFromStorage.indexOf(item);
if (index >= 0) {
todos.splice(index, 1);
localStorage.setItem('todoData', JSON.stringify(todos));
}
}
If you want to use different values.
Add a unique id field to each item and use it for the key.
localStorage.setItem("todoData" + Date.now(), JSON.stringify(newItem.value));
Note: Don't use iterate over localStorage fields, because you can potentially have other types of data also stored.

Update dynamically generated price of two boxes with select option

I am trying to make this work with the help of jQuery docs but not success so far.
I have two boxes paynow and payfull that has 0 initial value but I am filling these boxes dynamically (jQuery) with product prices.
Now I have to update these values further with select option to discount the price (multiply with data-percent). This is the HTML.
<select class="discount">
<option data-percent="0">Select Discount Coupon</option>
<option data-percent="5">ABCD</option>
<option data-percent="10">EFGH</option>
<option data-percent="15">IJKL</option>
</select>
<span class="price" id="paynow">$0.00</span>
<span class="price" id="payfull">$0.00</span>
EDIT: jQuery code
$(document).ready(function() {
// For Calculator
function Cost_Calculator() {
var Currency = '$';
var messageHTML = 'Please contact us for a price.';
function CostFilter(e) {
return e;
}
//Calculate function
function calculate() {
//Blank!
var CalSaveInfo = [];
$('#cost_calc_custom-data, #cost_calc_breakdown').html('');
//Calculate total
var calCost = 0;
var calculate_class = '.cost_calc_calculate';
$('.cost_calc_active').each(function() {
//Calculation
calCost = calCost + parseFloat($(this).data('value'));
//Add to list
var optionName = $(this).attr('value');
var appendName = '<span class="cost_calc_breakdown_item">' + optionName + '</span>';
var optionCost = $(this).attr('data-value');
var appendCost = '<span class="cost_calc_breakdown_price">' + Currency + optionCost + '</span>';
if (optionCost != "0") {
var appendItem = '<li>' + appendName + appendCost + '</li>';
}
//hidden data
var appendPush = ' d1 ' + optionName + ' d2 d3 ' + optionCost + ' d4 ';
$('#cost_calc_breakdown').append(appendItem);
CalSaveInfo.push(appendPush);
});
//Limit to 2 decimal places
calCost = calCost.toFixed(2);
//Hook on the cost
calCost = CostFilter(calCost);
var CustomData = '#cost_calc_custom-data';
$.each(CalSaveInfo, function(i, v) {
$(CustomData).append(v);
});
//Update price
if (isNaN(calCost)) {
$('#paynow').html(messageHTML);
$('#payfull').html(messageHTML);
$('.addons-box').hide();
} else {
$('#paynow').html(Currency + calCost);
$('#payfull').html(Currency + calCost);
$('.addons-box').show();
}
}
//Calculate on click
$('.cost_calc_calculate').click(function() {
if ($(this).hasClass('single')) {
//Add cost_calc_active class
var row = $(this).data('row');
//Add class to this only
$('.cost_calc_calculate').filter(function() {
return $(this).data('row') == row;
}).removeClass('cost_calc_active');
$(this).addClass('cost_calc_active');
} else {
// Remove class if clicked
if ($(this).hasClass('cost_calc_active')) {
$(this).removeClass('cost_calc_active');
} else {
$(this).addClass('cost_calc_active');
}
}
//Select item
var selectItem = $(this).data('select');
var currentItem = $('.cost_calc_calculate[data-id="' + selectItem + '"]');
var currentRow = currentItem.data('row');
if (selectItem !== undefined) {
if (!$('.cost_calc_calculate[data-row="' + currentRow + '"]').hasClass('cost_calc_active'))
currentItem.addClass('cost_calc_active');
}
//Bring in totals & information
$('#cost_calc_breakdown_container, #cost_calc_clear_calculation').fadeIn();
$('.cost_calc_hide').hide();
$('.cost_calc_calculate').each(function() {
calculate();
});
return true;
});
$('#cost_calc_clear_calculation').click(function() {
$('.cost_calc_active').removeClass('cost_calc_active');
calculate();
$('#cost_calc_breakdown').html('<p id="empty-breakdown">Nothing selected</p>');
return true;
});
}
//Run cost calculator
Cost_Calculator();
});
How about this one:
var totalPayNowPrice=parseFloat($('#paynow').text());
var totalPayFullPrice=parseFloat($('#payfull').text());
$('.discount').on('change',function(){
if(parseInt($('.discount option:selected').attr('data-percent'))){
$('#paynow').text((totalPayNowPrice*parseInt($('.discount option:selected').attr('data-percent')))+'$');
$('#payfull').text((totalPayFullPrice*parseInt($('.discount option:selected').attr('data-percent')))+'$');
}
});
Just put the $ sign in you spans after the numbers, in order to parse function would work.
JSFIDDLE
UPDATE
From another point I think there is a better solution to use prototype and store you current prices in spans inside global variable, then you can use them wherever you want. Here the pseudo prototype for your use, if you`d like just customize it for you using:
function Test(){
this.totalPayNowPrice=1;//the is 1 only for check code working
this.totalPayFullPrice=1;
}
Test.prototype={
init: function(){
var scope=this;
$('.discount').on('change',function(){
if(parseInt($('.discount option:selected').attr('data-percent'))){
$('#paynow').text((scope.totalPayNowPrice*parseInt($('.discount option:selected').attr('data-percent')))+'$');
$('#payfull').text((scope.totalPayFullPrice*parseInt($('.discount option:selected').attr('data-percent')))+'$');
}
},
updatePaynowPrice:function(newPrice){
this.totalPayNowPrice=totalPayNowPrice;
},
updatePayfullPrice:function(newPrice){
this.totalPayFullPrice=totalPayNowPrice;
}
}
you can use
$(document).ready(function(){
// get price from #paynow (just a number)
var getPaynow = $('#paynow').text().match(/\d+/);
// get price from #payfull (just a number)
var getPayfull = $('#payfull').text().match(/\d+/);
$('.discount').on('change', function(){
// get data-percent from selected option
var discount = parseFloat($(this).find('>option:selected').attr('data-percent'));
//alert(discount +'///'+ getPaynow+'///'+ getPayfull);
//update price for #paynow and #payfull
$('#paynow').text('$'+parseFloat(getPaynow - (getPaynow * discount / 100)));
$('#payfull').text('$'+parseFloat(getPayfull - (getPayfull * discount / 100)));
});
});
Working Demo
in your code you can update prices after this part of code
//Update price
if (isNaN(calCost)) {
$('#paynow').html(messageHTML);
$('#payfull').html(messageHTML);
$('.addons-box').hide();
} else {
$('#paynow').html(Currency + calCost);
$('#payfull').html(Currency + calCost);
$('.addons-box').show();
}
//get price from #paynow (just a number)
getPaynow = $('#paynow').text().match(/\d+/);
// get price from #payfull (just a number)
getPayfull = $('#payfull').text().match(/\d+/);

how to get dynamic id of dynamically created textbox in jquery

i want to perform keyup event via textbox id, and all textbox are dynamically created with onclick button event. for this i have to make 20 keyup function. if i use 20 keyup function then my code will become too lengthy and complex. instead of this i want to use a common function for all textbox. can anybody suggest me how to do it..thanks
here is what i am doing to solve it:
<div class="input_fields_wrap">
<button class="add_field_button">Add Booking</button></div>
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
var counter = 2;
$(".add_field_button").click(function() {
if (counter > 10) {
alert("Only 10 textboxes allow");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<div id="target"><label>Textbox #' + counter + ' : </label>' +
'<input type="text" name="textbox' + counter +
'" id="firsttextbox' + counter + '" value="" > <input type="text" name="textbox' + counter +
'" id="secondtextbox' + counter + '" value="" > Remove<input type="text" id="box' + counter + '" value="">sum</div>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
function check(a, b) {
var first = a;
var second = b;
var temp = temp;
var novalue = "";
result = parseInt(first) + parseInt(second);
if (!isNaN(result)) {
return result;
} else {
return novalue;
}
}
$(this).on("keyup", "#firsttextbox2", function(e) {
e.preventDefault();
var a = document.getElementById('firsttextbox2').value;
var b = document.getElementById('secondtextbox2').value;
var number = 2;
result = check(a, b);
document.getElementById('box2').value = result;
});
$(this).on("keyup", "#firsttextbox3", function(e) {
var number = 3;
e.preventDefault();
var a = document.getElementById('firsttextbox3').value;
var b = document.getElementById('secondtextbox3').value;
result = check(a, b);
document.getElementById('box3').value = result;
});
$(this).on("keyup", "#firsttextbox4", function(e) {
var number = 4;
e.preventDefault();
var a = document.getElementById('firsttextbox4').value;
var b = document.getElementById('secondtextbox4').value;
result = check(a, b);
final = document.getElementById('box4').value = result;
});
$(this).on("keyup", "#secondtextbox2", function(e) {
e.preventDefault();
var a = document.getElementById('firsttextbox2').value;
var b = document.getElementById('secondtextbox2').value;
result = check(a, b);
document.getElementById('box2').value = result;
});
$(this).on("keyup", "#secondtextbox3", function(e) {
e.preventDefault();
var a = document.getElementById('firsttextbox3').value;
var b = document.getElementById('secondtextbox3').value;
result = check(a, b);
document.getElementById('box3').value = result;
});
$(this).on("keyup", "#secondtextbox4", function(e) {
e.preventDefault();
var a = document.getElementById('firsttextbox4').value;
var b = document.getElementById('secondtextbox4').value;
result = check(a, b);
document.getElementById('box4').value = result;
});
$(this).on("click", "#remove_field", function(e) { //user click on remove text
e.preventDefault();
$(this).parent('#target').remove();
counter--;
});
});
</script>
See the snippet below to see how you can make this implementation more modular and useable. The trick is to think: what do I want to do? I want to be able to add multiple inputs and add their value, printing the result in another input.
It comes down to using classes - since we are going to use the same kind of thing for every row. Then apply something that works for all classes. No IDs whatsoever! You can even use the name property of the input that contains the value you want to save. Using the [] in that property will even pass you back a nice array when POSTING!
I know this looks like a daunting lot, but remove my comments and the number of lines reduces dramatically and this kind of code is almost infinitely extendable and reusable.
But have a look, this works and its simple and - most of all - it's DRY (don't repeat yourself 0 once you do, re-evaluate as there should be a better way!)!
Update
You could also use a <ol>as a wrapper and then add an <li> to this every time, so you get automatic counting of boxes in the front end without any effort from your end! Actually, thats so nice for this that I have changed my implementation.
var add = $('#add_boxes');
var all = $('#boxes');
var amountOfInputs = 2;
var maximumBoxes = 10;
add.click(function(event){
// create a limit
if($(".box").length >= maximumBoxes){
alert("You cannot have more than 10 boxes!");
return;
}
var listItem = $('<li class="box"></li>');
// we will add 2 boxes here, but we can modify this in the amountOfBoxes value
for(var i = 0; i < amountOfInputs; i++){
listItem.append('<input type="text" class="input" />');
}
listItem.append('<input type="text" class="output" name="value" />');
// Lets add a link to remove this group as well, with a removeGroup class
listItem.append('<input type="button" value="Remove" class="removeGroup" />')
listItem.appendTo(all);
});
// This will tie in ANY input you add to the page. I have added them with the class `input`, but you can use any class you want, as long as you target it correctly.
$(document).on("keyup", "input.input", function(event){
// Get the group
var group = $(this).parent();
// Get the children (all that arent the .output input)
var children = group.children("input:not(.output)");
// Get the input where you want to print the output
var output = group.children(".output");
// Set a value
var value = 0;
// Here we will run through every input and add its value
children.each(function(){
// Add the value of every box. If parseInt fails, add 0.
value += parseInt(this.value) || 0;
});
// Print the output value
output.val(value);
});
// Lets implement your remove field option by removing the groups parent div on click
$(document).on("click", ".removeGroup", function(event){
event.preventDefault();
$(this).parent(".box").remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<ol id="boxes">
</ol>
<input type="button" value="Add a row" id="add_boxes" />
You can target all your textboxes, present or future, whatever their number, with a simple function like this :
$(document).on("keyup", "input[type=text]", function(){
var $textbox = $(this);
console.log($textbox.val());
})
$("button").click(function(){
$("#container").append('<input type="text" /><br>');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<input type="text" /><br>
<input type="text" /><br>
<input type="text" /><br>
</div>
<button>Create one more</button>
You don't need complicated generated IDs, not necessarily a class (except if you have other input[type=text] you don't want to conflict with). And you don't need to duplicate your code and write 20 times the same function. Ever. If you're duplicating code, you're doing wrong.
Add classes "a" and "b" to the textboxes and "box" to the box. Then add data-idx attribute with the index (unused!?). Finally register the event handlers:
$('.a').on('keyup', function(e){
e.preventDefault();
var $this = $(this)
var $p = $this.parent()
var a= this.value;
var b= $p.find('.b').val()
var number =$this.data('idx') //unused!?
var result = check(a,b)
$p.find('.box').val(result)
})
$('.b').on('keyup', function(e){
e.preventDefault();
var $this = $(this)
var $p = $this.parent()
var a= $p.find('.a').val()
var b= this.value
var result = check(a,b)
$p.find('.box').val(result)
})
Or a general one:
$('.a,.b').on('keyup', function(e){
e.preventDefault();
var $p = $(this).parent()
var a= $p.find('.a').val()
var b= $p.find('.b').val()
var result = check(a,b)
$p.find('.box').val(result)
})
You can assign a class to all textboxes on which you want to perform keyup event and than using this class you can attach the event on elements which have that class. Here is an example
var html="";
for (var i = 0; i < 20; i++)
{
html += "<input type='text' id='txt" + i + "' class='someClass' />";
}
$("#testDiv").html(html);
Attach keyup event on elements which have class someClass.
$(".someClass").keyup(function () {
alert($(this).attr("id"));
});
A little helper to combine with your favorite answer:
var uid = function () {
var id = 0;
return function () {
return ++id;
};
}();
Usage:
uid(); // 1
uid(); // 2
uid(); // 3
Providing a code-snippet which may give you some hint:
$(".add_field_button").click(function ()
{
if (counter > 10)
{
alert("Only 10 textboxes allow");
return false;
}
var txtBoxDiv = $("<div id='TextBoxDiv"+counter+"' style='float:left;width:10%; position:relative; margin-left:5px;' align='center'></div>");
//creating the risk weight
var txtBox1 = $('<input />',
{
'id' : 'fst_textbox_' + counter,
'name' : 'textbox'+counter,
'type' : 'text',
'class' : 'input_field',
'onClick' : 'txtBoxFun(this,'+counter+')'
});
var txtBox2 = $('<input />',
{
'id' : 'sec_textbox_' + counter,
'name' : 'textbox'+counter,
'type' : 'text',
'class' : 'input_field',
'onClick' : 'txtBoxFun(this,'+counter+')'
});
var txtBox3 = $('<input />',
{
'id' : 'sum_textbox_' + counter,
'name' : 'textbox'+counter,
'type' : 'text',
'class' : 'input_field',
});
$(txtBoxDiv).append(txtBox1).append(txtBox2);
$(txtBoxDiv).append(txtBox3);
});
function txtBoxFun(obj, count)
{
var idGet = $(obj).attr('id');
var idArr = new Array();
idArr = idGet.split("_");
if(idArr[0] == "fst")
{
var sumTxt = parseInt(parseInt($(obj).val()) + parseInt($("#sec_textbox_"+count).val()));
}
else if(idArr[0] == "sec")
{
var sumTxt = parseInt(parseInt($(obj).val()) + parseInt($("#fst_textbox_"+count).val()));
}
$("#sum_textbox_"+count).val(sumTxt);
}

Access variables outside the jQuery .each() loop

I have a little bit complicated html structure.
I parse it to get this stuff:
Option1: value
Option2: value
from this like html:
<div class="option" id="option-691">
<span class="required">*</span>
<b>Option:</b><br>
<input type="radio" checked="" id="option-value-1250" value="1250" price="1156.0000" name="option[691]">
<label for="option-value-1250">2,35 xx - 1156.00 </label>
<br>
<input type="radio" onchange="recalculateprice();reloadpr();" id="option-value-1251" value="1251" price="506.0000" price_prefix="" points="0" name="option[691]">
<label for="option-value-1251">900 xx - 506.00</label>
<br>
</div>
and this too
<div class="option" id="option-690">
<span class="required">*</span>
<b>Option:</b><br>
<select name="option[690]">
<option price="1156.0000" price_prefix="+" points="0" value="1249">value01
(+1156.00)
</option>
<option price="1156.0000" price_prefix="+" points="0" value="1248">value02
(+1156.00)
</option>
<option price="1156.0000" price_prefix="+" points="0" value="1247">value03
(+1156.00)
</option>
</select>
</div>
And using this I can get data from both types (inputs + selects).
$('#product_options > div.option').each(function() {
var Opt01 = ( $(this).find('option:selected').parent().parent().find('b').text() + $(this).find('option:selected').text() );
var Opt02 = ( $(this).find('input:checked').parent().find('b').text() + $(this).find('input:checked').next().text() );
console.log(Opt01);
console.log(Opt02);
});
But, I want to get Opt01 and Opt02 outside the .each() loop. How I can do this?
Variables declared within functions can't be accessed outside of them. Just declare them outside of the loop:
var Opt01;
var Opt02;
$('#product_options > div.option').each(function() {
Opt01 = ( $(this).find('option:selected').parent().parent().find('b').text() + $(this).find('option:selected').text() );
Opt02 = ( $(this).find('input:checked').parent().find('b').text() + $(this).find('input:checked').next().text() );
console.log(Opt01);
console.log(Opt02);
});
I want to get Opt01 and Opt02 outside the .each() loop
Since the variables are local in that context (by using var keyword), outside of the each callback the variables are undefined. You could define them outside of the each callback, e.g. var opt1, opt2;, but what will happen? In each iteration the values are overridden and the last values win. If the selector returns 1 element then each shouldn't be used in the first place.
You could define a function and pass the values to it.
$('#product_options > div.option').each(function() {
var Opt1 = '...';
var Opt2 = '...';
doSomething(Opt1, Opt2);
});
Or use the map method and create an array of objects:
var options = $('#product_options > div.option').map(function() {
var opt01 = '...';
var opt02 = '...';
return {
opt1: opt01,
opt2: opt02
}
}).get();
Just declare the variable outside the each loop. Variables declared inside the function can be accessed only from inside. JsFiddle
var Opt01, Opt02;
function find(){
$('#product_options > div.option').each(function() {
var option1 = ( $(this).find('option:selected').parent().parent().find('b').text() + $(this).find('option:selected').text() );
var option2 = ( $(this).find('input:checked').parent().find('b').text() + $(this).find('input:checked').next().text() );
if(option1){
Opt01 = option1;
console.log("inside: "+Opt01);
}
if(option2){
Opt02 = option2;
console.log("inside: "+Opt02);
}
});
console.log("outside: "+Opt01);
console.log("outside: "+Opt02);
}
It's very simple,
You have to declare your variables outside of your function as global.
But don't declare only,assign some value
Var opt1=0;
Thanks guys. I've added another validation rule before loop and code looks like this, so far. And it works fine:
if ($('#product_options div.option').length) {
$('#product_options > div.option').each(function () {
//defining
OptionTitle = $(this).find('option:selected').parent().parent().find('b').text();
OptionValue = $(this).find('option:selected').text();
InputTitle = $(this).find('input:checked').parent().find('b').text();
InputValue = $(this).find('input:checked').next().text();
//
if (OptionTitle != '' && OptionValue != '') {
Opt01 = (OptionTitle + OptionValue)
}
if (InputTitle != '' && InputValue != '') {
Opt02 = (InputTitle + InputValue)
}
});
//get values outside the loop
console.log('Options detected');
if (typeof Opt01 === 'undefined') {
Opt01 = ''
}
if (typeof Opt02 === 'undefined') {
Opt02 = ''
}
console.log('Opt01 = ' + Opt01);
console.log('Opt02 = ' + Opt02);
}
else {
console.log('Options are empty');
var Opt01 = '';
var Opt02 = '';
console.log('Opt01 = ' + Opt01);
console.log('Opt02 = ' + Opt02);
}
Also, fiddle is here http://jsfiddle.net/caLj2xbe/

Categories