I have a function using which I am getting the auto sum for a particular field in a row.
$(function () {
$('#add_iaDetails_table').on('change', '[name=days_0]', function () {
var $row = $(this).closest('tr');
var $rate = $row.find('input[name=rate_0]');
var $days = $row.find('input[name=days_0]');
var $cost = $row.find('input[name=cost_0]');
var rate = parseFloat($rate.val());
var days = parseFloat($days.val());
$cost.val(rate * days);
});
});
But the thing is I am appending the rows in the table dynamically and I am the name of the fields as well eg. days_1,days_2.....rate_1,rate_2....
My function here will calculate the autosum for only the first row which matches with values given in function.
Is there any way in which I can match all the appended values like days_* , rate_*
Please suggest a solution. Thanks in advance.
A simple
$(function () {
$('#add_iaDetails_table').on('change', '[name=days_0]', function () {
var $row = $(this).closest('tr');
var $rate = $row.find('input[name*=rate_]');
var $days = $row.find('input[name*=days_]');
var $cost = $row.find('input[name*=cost_]');
var rate = parseFloat($rate.val());
var days = parseFloat($days.val());
$cost.val(rate * days);
});
});
would work where * implies that you select any input with attribute containing the given string or you may use the startswith selector from JQUERY where in above code you replace * by ^
To accommodate dynamic content, I would be a bit more flexible with your selector; just filter on the name starting with days_, and then grab that id at the end dynamically.
Something like this:
$('#add_iaDetails_table').on('change', '[name^=days_]', function () {
var name = $(this).attr('name');
var nameId = name.substr(name.indexOf('_') + 1);
var $row = $(this).closest('tr');
var $rate = $row.find('input[name=rate_' + nameId + ']');
var $days = $row.find('input[name=days_' + nameId + ']');
var $cost = $row.find('input[name=cost_' + nameId + ']');
var rate = parseFloat($rate.val());
var days = parseFloat($days.val());
$cost.val(rate * days);
});
you can use starts-with selector, like
$('#add_iaDetails_table').on('change', '[name^=days_]', function () {
var uid = $(this).attr("name").split("_")[1]; //get the unique id from 'name' attribute
var $row = $(this).closest('tr');
var $rate = $row.find('input[name=rate_' + uid + ']');
var $days = $row.find('input[name=days_' + uid + ']');
var $cost = $row.find('input[name=cost_' + uid + ']');
var rate = parseFloat($rate.val());
var days = parseFloat($days.val());
$cost.val(rate * days);
});
jQuery has a whole bunch of different selectors
http://api.jquery.com/category/selectors/
Based on your question you probably want the Starts With refiner
http://api.jquery.com/attribute-starts-with-selector/
$('#add_iaDetails_table').on('change', '[name=^days_]', function () { ... }
The scalable/cross browser solution I can think of is, for every input element add a class that you can identify row/column index. This way you can do horizontal or vertical queries and do whatever you want.
Related
I've got a pricing page with two plans. On the first pricing plan, I'm adding a feature where a user can type in a value and a price for that value will return on the right-hand side (onkeyup). See how it works here. This is the code that has already been implemented:
var inputBox = document.getElementById('orderValue');
inputBox.onkeyup = function() {
document.getElementById('deliveryPrice').innerHTML = inputBox.value;
}
I need to add a formula to the output value, (value * 0.025) + 4. Then I would need to format everything as a currency (£000,000.000) onkeyup too and output value. Can anyone help?
var elDeliveryPrice = document.getElementById('deliveryPrice');
var elOrderValue = document.getElementById('orderValue');
var formatter = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });
elOrderValue.addEventListener('keyup', _ => {
let curVal = elOrderValue.value;
let curValFloat = parseFloat(curVal);
if (isNaN(curValFloat)) {
elDeliveryPrice.innerHTML = '';
return;
}
elDeliveryPrice.innerHTML = formatter.format((curValFloat * 0.025) + 4);
});
You can store the result of your formula in a new variable and then use toLocaleString() to convert your new number into a string which is comma separated. Lastly you can use the HTML entity £ as a prefix to your new value to add the pounds symbol.
See working example below:
var inputBox = document.getElementById('orderValue');
var outputElem = document.getElementById('deliveryPrice');
inputBox.onkeyup = function() {
var newValue = this.value * 0.025 + 4;
outputElem.innerHTML = "£" + newValue.toLocaleString();;
}
<input type="number" id="orderValue" />
<span id="deliveryPrice"></span>
You can use regex to add space after every 3 characters and add £ to add the currency symbol
var inputBox = document.getElementById('orderValue');
inputBox.onkeyup = function(){
var val = (Number(inputBox.value)* 0.025) + 4;
val = val.toFixed(3).replace(/\d(?=(\d{3})+\.)/g, ' ')
document.getElementById('deliveryPrice').innerHTML = "£ "+val;
}
here is the complete working code. See Sacreenshot http://prntscr.com/mazqw1
var inputBox = document.getElementById('orderValue');
inputBox.onkeyup = function(){
var x=parseFloat(Math.round(((inputBox.value* 0.025) + 4) * 100) / 100).toFixed(3);
var x=x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
document.getElementById('deliveryPrice').innerHTML =x;
}
I am using CodeIgniter & jQuery and parsedown/markdown When I open my bootstrap modal, it allows me to create a new Reference-style link like on here.
I am trying to be able to find some how where it can find the next free number for my available in my textarea and when click save in model will set it.
I am fine [exmple-1][1] and [example-3][3]
[1]: http://www.example.com
[3]: http://www.example.com
And when I open my bootstrap modal and create a new hyperlink it will set and add the next available number
Here is the Codepen Example
Question: How can I when I create a new hyperlink in my bootstrap modal
and click save it can find the next available number set it. Because only 1 & 3 are set in example above next one should be 2 when click save in model
currently as you can see below I just use var counter = 1; and counter++; to be able to create numbers.
Script:
$('#myLink').on('shown.bs.modal', function() {
var text = getSelectedText();
$('#title').val(text.trim());
$('#url').val('http://');
});
function getSelectedText() {
var textarea = document.getElementById("message");
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var sel = textarea.value.substring(start, end);
return sel;
}
var counter = 1;
$('#save-link').on('click', function(e) {
var textarea = document.getElementById("message");
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var sel = textarea.value.substring(start, end);
var replace = '[' + $('input#title').val() + ']' + '[' + counter + ']';
var id = '\n [' + counter + ']: ' + $('input#url').val();
counter++;
if ($('#title').val().length > 0) {
textarea.value = textarea.value.substring(0,start) + replace +
textarea.value.substring(end,len) + ' \n' + id;
$('#myLink').modal('hide');
//$('#myLink form')[0].reset();
} else {
return false;
}
});
You can use a simple regex to find the used numbers in the textarea:
function findAvailableNumber(textarea){
//Find lines with links
var matches = textarea.value.match(/(^|\n)\s*\[\d+\]:/g);
//Find corresponding numbers
var usedNumbers = matches.map(function(match){
return parseInt(match.match(/\d+/)[0]); }
);
//Find first unused number
var number = 1;
while(true){
if(usedNumbers.indexOf(number) === -1){
//Found unused number
return number;
}
number++;
}
return number;
}
Add the function, remove the line var counter = 1; and replace counter++; with var counter = findAvailableNumber(textarea);
JSFiddle
As Barmar said: store your already generated numbers in an object or an array and check for the next non-existing number:
var existingNumbers = [1, 3];
function getNextNumber() {
var i = 1;
while (existingNumbers.indexOf(i) > - 1) {
i++;
}
existingNumbers.push(i);
return i;
}
Then get the next number with:
var number = getNextNumber();
I cant figure out where I have gone wrong. I am trying to have it so that a random index is selected then from that index the corresponding item in the array is chosen and displayed. However, at the moment nothing is being displayed. I think this is because the functions are not loading after the page has loaded and I'm not sure how to do this correctly. If you see any other errors in my current code please feel free to leave some feedback. Thanks :)
JS
<script type="text/javascript">
$(document).ready(function() {
function getRandomVideo() {
//Arrays for videos, titles, images, and searches
var videos = ['https://www.youtube.com/embed/kiTO7c_qeZs', 'https://www.youtube.com/embed/z4Hfv00eqoI', 'https://www.youtube.com/embed/7cdZYQB5ONE', 'https://www.youtube.com/embed/i1gE3nyQnKg', ];
var titles = ['Beethoven - Music, Love and Wine', 'Mozart String Serenade No.13', 'Beethoven Sonata No. 31 in A Flat Major', "Debussy - Children's Corner", ];
var images = ["url('Assets/beethoven.jpg')", "url('Assets/mozart.jpg')", "url('Assets/beethoven.jpg')", "url('Assets/debussy.jpg')", ]
var searches = ['beethoven+biography&s=0', 'wolfgang+mozart&s=0', 'beethoven+biography&s=0', 'Claude+Debussy&s=1', ];
//Gets a random index then uses said index to select an option in the array
var rand = Math.floor(Math.random() * videos.length);
var video = videos[rand];
var title = titles[rand];
var image = images[rand];
var search = searches[rand];
//replaces parts of html with selected option from array
document.getElementById("songTitle").innerHTML = title;
document.getElementById("img").style.backgroundImage = image;
document.getElementById("randomVideo").src = video;
return search
}
var apiKey = "jja10ssv4950uh65";
//I want to do this function and the one abovevwhen the document is loaded
$(document).onload(function() {
var searchTerm = getRandomVideo();
var url = "http://api.trove.nla.gov.au/result?key=" + apiKey + "&encoding=json&zone=newspaper&sortby=relevance&q=" + searchTerm + "&s=0&n=5&include=articletext,pdf&encoding=json&callback=?";
console.log(url);
$.getJSON(url, function(data) {
$('#output').empty();
$.each(data.response.zone[0].records.article, function(index, value) {
$("#output").append("<p>" + value.articleText + "</p>");
});
});
});
});
</script>
When you call the function try like this...E.g:
<button onclick="$(function(){getRandomVideo()});">Test</button>
And let
<script type="text/javascript">
function getRandomVideo() {
// Your codes..
}
</script>
Remove the onload part from from your jquery code and it will work.
$(document).ready(function() {
function getRandomVideo() {
//Arrays for videos, titles, images, and searches
var videos = ['https://www.youtube.com/embed/kiTO7c_qeZs', 'https://www.youtube.com/embed/z4Hfv00eqoI', 'https://www.youtube.com/embed/7cdZYQB5ONE', 'https://www.youtube.com/embed/i1gE3nyQnKg', ];
var titles = ['Beethoven - Music, Love and Wine', 'Mozart String Serenade No.13', 'Beethoven Sonata No. 31 in A Flat Major', "Debussy - Children's Corner", ];
var images = ["url('Assets/beethoven.jpg')", "url('Assets/mozart.jpg')", "url('Assets/beethoven.jpg')", "url('Assets/debussy.jpg')", ]
var searches = ['beethoven+biography&s=0', 'wolfgang+mozart&s=0', 'beethoven+biography&s=0', 'Claude+Debussy&s=1', ];
//Gets a random index then uses said index to select an option in the array
var rand = Math.floor(Math.random() * videos.length);
var video = videos[rand];
var title = titles[rand];
alert(title);
var image = images[rand];
var search = searches[rand];
//replaces parts of html with selected option from array
document.getElementById("songTitle").innerHTML = title;
document.getElementById("img").style.backgroundImage = image;
document.getElementById("randomVideo").src = video;
return search
}
var apiKey = "jja10ssv4950uh65";
//I want to do this function and the one abovevwhen the document is loaded
var searchTerm = getRandomVideo();
var url = "http://api.trove.nla.gov.au/result?key=" + apiKey + "&encoding=json&zone=newspaper&sortby=relevance&q=" + searchTerm + "&s=0&n=5&include=articletext,pdf&encoding=json&callback=?";
console.log(url);
$.getJSON(url, function(data) {
$('#output').empty();
$.each(data.response.zone[0].records.article, function(index, value) {
$("#output").append("<p>" + value.articleText + "</p>");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="songTitle"></div>
.onload is not a jQuery method . At .ready() at beginning of js document should be loaded at call to $.getJSON()
$(document).ready(function() {
// do stuff
var apiKey = "jja10ssv4950uh65";
var searchTerm = getRandomVideo();
var url = "http://api.trove.nla.gov.au/result?key=" + apiKey + "&encoding=json&zone=newspaper&sortby=relevance&q=" + searchTerm + "&s=0&n=5&include=articletext,pdf&encoding=json&callback=?";
console.log(url);
$.getJSON(url, function(data) {
$('#output').empty();
$.each(data.response.zone[0].records.article, function(index, value) {
$("#output").append("<p>" + value.articleText + "</p>");
});
});
})
Probable something really stupid but suppose I have 2 elements that match $('[id$=_product_id]') why are the change events not matched properly?
var numberPattern = /\d+/g;
$('[id$=_product_id]').each(function(idx, elem) {
recordId = elem.id.match(numberPattern)
productId = elem.value;
console.log(recordId);
$("#client_order_order_lines_attributes_" + recordId + "_product_id").on("change", function(e) {
console.log(recordId);
})
});
I created a fiddle that demonstrates this http://jsfiddle.net/hLYpE/1/
What am I missing?
You need to declare those variables, that's the danger of implicit globals.
var recordId = elem.id.match(numberPattern);
var productId = elem.value;
Demo: http://jsfiddle.net/elclanrs/hLYpE/4/
You should change the code adding the var in front of the name of the variables:
var numberPattern = /\d+/g;
$('[id$=_product_id]').each(function(idx, elem) {
var recordId = elem.id.match(numberPattern),
productId = elem.value;
console.log(recordId);
$("#client_order_order_lines_attributes_" + recordId + "_product_id").on("change", function(e) {
console.log(recordId);
})
});
I'm using the jqgrid, and to focus the popup to add, delete and edit, I need to use the parameter beforeShowForm that before this show window, shows the center of the screen. The problem is I have to always do the same code for these three functions.
The function is as follows:
{ // edit option
beforeShowForm: function(form) {
var dlgDiv = $("#editmod" + $(this)[0].id);
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
var parentTop = parentDiv.offset().top;
var parentLeft = parentDiv.offset().left;
dlgDiv[0].style.top = Math.round(parentTop / 2) + "px";
dlgDiv[0].style.left = Math.round(parentLeft + (parentWidth-dlgWidth )/2 ) + "px";
}
},
In order to reuse the same code, I would create a separate function to be always writing the same amount of code. I tried to create the following function:
Function:
function test(dlgDiv)
{
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
var parentTop = parentDiv.offset().top;
var parentLeft = parentDiv.offset().left;
dlgDiv[0].style.top = Math.round(parentTop / 2) + "px";
dlgDiv[0].style.left = Math.round(parentLeft + (parentWidth-dlgWidth )/2 ) + "px";
}
In Grid:
{ // edit option
beforeShowForm: function(form) {
var dlgDiv = $("#editmod" + $(this)[0].id);
test(dlgDiv);
}
},
But continued without giving. Says that the value dlgDiv is not defined. Does anyone know how to solve this?
The issue lies in the selector you use here:
var dlgDiv = $("#editmod" + $(this)[0].id);
Whatever element you're trying to get isn't being returned, because the selector can't find it. You should revise your selector to reflect the ID of the element you're attempting to find.
If you've done that and you still have an issue, the problem lies with your context and this doesn't mean what you think it means in the above line of code. You'll have to show us more code before I can elaborate on that, though.