Javascript Dynamic Fieldset and sum - javascript

I am using a script that adds a fieldset to my form but I am having one glitch that I can not figure out and would appreciate any insight you can provide.
Here is the trouble:
The duplication of the fieldset works great.
I have another script which is creating a sum of the fields named "unitPrice" in the original fieldset. When I add a new fieldset with the new unitPrice fields do not get calculated into the sum. I am sure they are being renamed but what name would I use and how do I write it into the calculation so that I have a total of all of the unitPrice fields?
Thanks for your help.
Here is the Fieldset script:
<script>
function insertAfter(newElement, targetElement)
{
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement)
{
parent.appendChild(newElement);
}
else
{
parent.insertBefore(newElement, targetElement.nextSibling);
}
}
// Suffix + Counter
var suffix = ':';
var counter = 1;
// Clone nearest parent fieldset
function cloneMe(a)
{
// Increment counter
counter++;
// Find nearest parent fieldset
var original = a.parentNode;
while (original.nodeName.toLowerCase() != 'fieldset')
{
original = original.parentNode;
}
var duplicate = original.cloneNode(true);
// Label - For and ID
var newLabel = duplicate.getElementsByTagName('label');
for (var i = 0; i < newLabel.length; i++)
{
var labelFor = newLabel[i].htmlFor
if (labelFor)
{
oldFor = labelFor.indexOf(suffix) == -1 ? labelFor : labelFor.substring(0, labelFor.indexOf(suffix));
newLabel[i].htmlFor = oldFor + suffix + counter;
}
var labelId = newLabel[i].id
if (labelId)
{
oldId = labelId.indexOf(suffix) == -1 ? labelId : labelId.substring(0, labelId.indexOf(suffix));
newLabel[i].id = oldId + suffix + counter;
}
}
// Input - Name + ID
var newInput = duplicate.getElementsByTagName('input');
for (var i = 0; i < newInput.length; i++)
{
var inputName = newInput[i].name
if (inputName)
{
oldName = inputName.indexOf(suffix) == -1 ? inputName : inputName.substring(0, inputName.indexOf(suffix));
newInput[i].name = oldName + suffix + counter;
}
var inputId = newInput[i].id
if (inputId)
{
oldId = inputId.indexOf(suffix) == -1 ? inputId : inputId.substring(0, inputId.indexOf(suffix));
newInput[i].id = oldId + suffix + counter;
}
}
// Select - Name + ID
var newSelect = duplicate.getElementsByTagName('select');
for (var i = 0; i < newSelect.length; i++)
{
var selectName = newSelect[i].name
if (selectName)
{
oldName = selectName.indexOf(suffix) == -1 ? selectName : selectName.substring(0, selectName.indexOf(suffix));
newSelect[i].name = oldName + suffix + counter;
}
var selectId = newSelect[i].id
if (selectId)
{
oldId = selectId.indexOf(suffix) == -1 ? selectId : selectId.substring(0, selectId.indexOf(suffix));
newSelect[i].id = oldId + suffix + counter;
}
}
// Textarea - Name + ID
var newTextarea = duplicate.getElementsByTagName('textarea');
for (var i = 0; i < newTextarea.length; i++)
{
var textareaName = newTextarea[i].name
if (textareaName)
{
oldName = textareaName.indexOf(suffix) == -1 ? textareaName : textareaName.substring(0, textareaName.indexOf(suffix));
newTextarea[i].name = oldName + suffix + counter;
}
var textareaId = newTextarea[i].id
if (textareaId)
{
oldId = textareaId.indexOf(suffix) == -1 ? textareaId : textareaId.substring(0, textareaId.indexOf(suffix));
newTextarea[i].id = oldId + suffix + counter;
}
}
duplicate.className = 'duplicate';
insertAfter(duplicate, original);
}
// Delete nearest parent fieldset
function deleteMe(a)
{
var duplicate = a.parentNode;
while (duplicate.nodeName.toLowerCase() != 'fieldset')
{
duplicate = duplicate.parentNode;
}
duplicate.parentNode.removeChild(duplicate);
}
</script>
Here is the script I am using for the calculation:
<script type="text/javascript">
function myFunction(){
var the_fields = document.getElementsByName("unitPrice");
var the_sum = 0;
for (var i=0; i<the_fields.length; i++){
if (the_fields[i].value != ""
&& !isNaN(the_fields[i].value))
{
the_sum += Number(the_fields[i].value);
}
}
document.repairform.sum.value = (the_sum.toFixed(2));
}
</script>

I guess that you need to call "myfunction" each time a new field is being added.
When someone loads your page , the "myfunction" calculate the sum of the "existing" fields at the current. When you duplicate the fields you need to re-call "myfunction" so it will update the sum according to the new duplicated fields.

Related

Slight trouble with table row fetch script

I'm kinda new to scripting and all and just wanted to know if anyone could help me edit my code to hide the whole table from the start and then just display the rows that match the keyword.
Right now what the code does is:
You enter a keyword in an inputbox
The script searches through a table looking for rows matching the keyword.
Hide all other rows.
But i would like it to work another way, but don't really know how to.
What i would like it to do is:
Display the inputbox only on the page.(Table is hidden)
Display the results that match the keyword without displaying the whole table.
Code:
var TableSearch = function(searchBoxId, dataTableId, options) {
this.searchBox = document.querySelector('#' + searchBoxId);
this.dataTable = document.querySelector('#' + dataTableId);
this.options = options;
}
TableSearch.prototype = {
init: function(searchBoxId, dataTableId, options) {
// defaults options
var settings = {
firstRowHeader: true,
highlightCss: "style='background-color:yellow'",
noResultsText: null
};
if (this.options) {
for (var key in settings) {
// Update settings if valid option and value was supplied.
if (this.options.hasOwnProperty(key) && (this.options[key] != null && this.options[key].toString() != '')) {
if (key == 'highlightCss') {
settings[key] = "class='" + this.options[key] + "'";
continue;
}
settings[key] = this.options[key];
}
}
}
this.options = settings;
this.searchBox.addEventListener('keyup', this.search.bind(this), false);
},
search: function(e) {
if(e.keyCode == 27) {
this.searchBox.value = ''; // Clear search on Esc
}
this.toggleNoResult('remove');
var keyword = this.escapeSpecialChars(this.searchBox.value);
var textSearchRegex = new RegExp(keyword, "ig"); // case in-sensitive
var rowDisplay, rowObj, rowHtml, match;
var firstRowIndex = (this.options.firstRowHeader == true) ? 1 : 0;
for (var rowIndex = firstRowIndex; rowIndex < this.dataTable.rows.length; rowIndex++) {
rowDisplay = '';
rowObj = this.dataTable.rows.item(rowIndex);
rowHtml = rowObj.innerHTML.replace(/<mark[^/>]*>/g,'').replace(/<\/mark>/g,''); // remove previous highlighting
if (keyword == '')
rowDisplay = 'table-row';
else {
match = rowHtml.replace(/<[^>]*>/g, '').match(textSearchRegex); // strip html tags and search for keyword
if(match) {
// Get unique matches: http://stackoverflow.com/a/21292834/1440057
match = match.sort().filter(function(element, index, array) { return index == array.indexOf(element); });
var tempHtml = rowHtml;
for (var i = 0; i < match.length; i++)
tempHtml = this.highlight(tempHtml, match[i]);
if (tempHtml.search(/<\/mark>/g) > -1) {
rowHtml = tempHtml;
rowDisplay = 'table-row';
}
else // Keyword did not match with any column content
rowDisplay = 'none';
}
else // Keyword did not match even in the row text content
rowDisplay = 'none';
}
rowObj.innerHTML = rowHtml;
rowObj.style.display = rowDisplay;
}
// Check if 'no results' row needs to be added
if (keyword != '' && this.options.noResultsText && this.dataTable.innerHTML.search(/style=\"display: table-row;\"/g) == -1)
this.toggleNoResult('add');
},
highlight: function(rowHtml, match) {
var row = document.createElement('tr');
row.innerHTML = rowHtml;
var textReplaceRegex = new RegExp(this.escapeSpecialChars(match), "g"); // case sensitive
var highlightMarkup = '<mark ' + this.options.highlightCss + '>' + match + '</mark>';
var cell = null;
var htmlOut = '';
for (var i = 0; i < row.cells.length; i++) {
cell = row.cells.item(i);
// Highlighting works only for direct text content, not nested tags.
// e.g. searching "blog" in <td>my blog</td> won't work.
if (cell.children.length == 0) {
if (cell.textContent.indexOf(match) > -1) {
// Match found in this cell, highlight it
htmlOut += '<td>' + cell.textContent.replace(textReplaceRegex, highlightMarkup) + '</td>';
continue;
}
}
htmlOut += '<td>' + cell.innerHTML + '</td>';
}
return htmlOut;
},
escapeSpecialChars: function(inStr) {
return inStr.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
},
toggleNoResult: function(mode) {
var noResultsRow;
if (mode == 'add') {
noResultsRow = this.dataTable.insertRow(this.dataTable.rows.length);
noResultsRow.setAttribute('id', 'noResultsRow');
var noResultsRowCell = noResultsRow.insertCell(0);
noResultsRowCell.setAttribute('colspan', this.dataTable.rows[0].cells.length);
noResultsRowCell.setAttribute('align', 'center');
noResultsRowCell.textContent = this.options.noResultsText;
}
else if (mode == 'remove') {
noResultsRow = this.dataTable.querySelector('#noResultsRow');
if (noResultsRow != null) {
this.dataTable.deleteRow(this.dataTable.rows.length - 1);
}
}
}
}
Thanks in advance :)

How to change this code to list post titles of all the post on Blogger in format YYYY.MM.DD <title> and chronological order?

I like to show my titles of posts on a specific page. It is more effective to get know what author have written than scroll all pages or navigate using archive widget.
I found code (code is below) for generate list that sort post titles alphabetically but I like to show titles in chronological order. There is lot of code example about this but they are outdated. They doesn’t work anymore after some changes in blogger platform.
How to change code to get post titles in chronological order and in format YYYY.MM.DD ?
<div>
<ul id="postList12"></ul>
</div>
<script type="text/javascript">
var startIndex = 1;
var maxResults = 150;
var allResults = [];
function sendQuery12() {
var scpt = document.createElement("script");
scpt.src = "/feeds/posts/summary?alt=json&callback=processPostList12&start-index=" + startIndex + "&max-results=" + maxResults;
document.body.appendChild(scpt);
}
function printArrayResults(root) {
//Sort Alphebetically
allResults.sort(function(a, b)
{
var a_string = a.children[0].textContent ;
var b_string = b.children[0].textContent ;
if(a_string < b_string) return -1;
if(a_string > b_string) return 1;
return 0;
})
var elmt = document.getElementById("postList12");
for (index = 0; index < allResults.length; index++) {
elmt.appendChild(allResults[index]);
}
}
function processPostList12(root) {
var elmt = document.getElementById("postList12");
if (!elmt)
return;
var feed = root.feed;
if (feed.entry.length > 0) {
for (var i = 0; i < feed.entry.length; i++) {
var entry = feed.entry[i];
var title = entry.title.$t;
var date = entry.published.$t
for (var j = 0; j < entry.link.length; j++) {
if (entry.link[j].rel == "alternate") {
var url = entry.link[j].href;
if (url && url.length > 0 && title && title.length > 0) {
var liE = document.createElement("li");
var a1E = document.createElement("a");
a1E.href = url;
a1E.textContent = title + " (" + date.substr(0,10) + ")";
liE.appendChild(a1E);
//elmt.appendChild(liE);
allResults.push(liE);
}
break;
}
}
}
if (feed.entry.length >= maxResults) {
startIndex += maxResults;
sendQuery12();
} else {
printArrayResults();
}
}
}
sendQuery12();
</script>
Code is copied from here: https://dansator.blogspot.fi/2015/10/general-alphabetical-list-of-posts.html
Remove sort method from the code. remove the following :
//Sort Alphebetically
allResults.sort(function(a, b){
var a_string = a.children[0].textContent ;
var b_string = b.children[0].textContent ;
if(a_string < b_string) return -1;
if(a_string > b_string) return 1;
return 0;
})
Your code should be
<div>
<ul id="postList12"></ul>
</div>
<script type="text/javascript">
var startIndex = 1;
var maxResults = 150;
var allResults = [];
function sendQuery12()
{
var scpt = document.createElement("script");
scpt.src = "/feeds/posts/summary?alt=json&callback=processPostList12&start-index=" + startIndex + "&max-results=" + maxResults;
document.body.appendChild(scpt);
}
function printArrayResults(root)
{
var elmt = document.getElementById("postList12");
for (index = 0; index < allResults.length; index++) {
elmt.appendChild(allResults[index]);
}
}
function processPostList12(root)
{
var elmt = document.getElementById("postList12");
if (!elmt)
return;
var feed = root.feed;
if (feed.entry.length > 0)
{
for (var i = 0; i < feed.entry.length; i++)
{
var entry = feed.entry[i];
var title = entry.title.$t;
var date = entry.published.$t
for (var j = 0; j < entry.link.length; j++)
{
if (entry.link[j].rel == "alternate")
{
var url = entry.link[j].href;
if (url && url.length > 0 && title && title.length > 0)
{
var liE = document.createElement("li");
var a1E = document.createElement("a");
a1E.href = url;
a1E.textContent = title + " (" + date.substr(0,10) + ")";
liE.appendChild(a1E);
//elmt.appendChild(liE);
allResults.push(liE);
}
break;
}
}
}
if (feed.entry.length >= maxResults)
{
startIndex += maxResults;
sendQuery12();
} else {
printArrayResults();
}
}
}
sendQuery12();
</script>

Not able add multiple option to select

function successCallback(caRecords) {
var x = document.getElementById("custAccount"); // select
var option1 = document.createElement("option"); //options
//var accno = 0;
// caRecords i am fetch from MS CRM
var count = caRecords[0].results.length;
if (caRecords != null && count > 0) {
alert("records are not null");
for (var i = 0 ; i < count; i++)
{
var text = caRecords[0].results[i].new_name;
// alert(text + "J=" + j);
option1.text = text;
option1.value = j;
x.add(option1);
j++;
}
}
I got six records and try to insert that values into select as option. It showing last value of my 6 values.
Can anyone help me to improve my code?
You can iterate your values like this...
function successCallback(caRecords) {
var x = document.getElementById("custAccount"); // select
var options = "";
var count = caRecords[0].results.length;
if (caRecords != null && count > 0) {
alert("records are not null");
for (var i = 0; i < count; i++) {
options += "<option value=" + j + ">" + caRecords[0].results[i].new_name + "</option>";
j++;
}
x.innerHTML = options;
}

replacing text that has url with an anchor with regex

var a = document.querySelectorAll('.post .content div');
var b = a[7].childNodes;
for(i=0;i<b.length;i++){
var exp = /(\b(https?|ftp|file):\/\/[\-A-Z0-9+&##\/%?=~_|!:,.;]*[\-A-Z0-9+&##\/%=~_|])/ig;
if(b[i].nodeType === 3){
var ahref = document.createElement('a');
ahref.className="easyBBurlFetch";
ahref.href=b[i].nodeValue.replace(exp,'$1');
ahref.innerText=b[i].nodeValue.replace(exp,'$1');
b[i].parentNode.insertBefore(ahref,b[i]);
b[i].parentNode.removeChild(b[i].nextSibling);
}
}
Someone gave me the answer as I had this code though it wasn't working correct. Though I have the issue now if my text is like so:
This is just a test so click here www.youtube.com which then becomes
www.youtube.com%20which%20then%20becomes
It doesn't event keep the first line of text, I just need to parse the url while keeping the surrounding text.
In need the output to save the actual surrounding text but parse the urls that are inside the text to html anchor tags <a> so that they can then be clickable and actually follow through to a real website and not have unnessarcy text inside it from what my user was writing about. Thank you
UPDATE
I've got closer to making this work-- But I'm having a problem with the first text in the string is saying Undefined I've been debugging this and can't seem to figure out why this is happening. Here is code
var a = document.querySelectorAll('.post');
var b = a[0].childNodes;
var textArray;
var ahref;
for (i = 0; i < b.length; i++) {
var exp = /(\b(https?|ftp|file):\/\/[\-A-Z0-9+&##\/%?=~_|!:,.;]*[\-A-Z0-9+&##\/%=~_|])/ig;
if (b[i].nodeType === 3) {
var newHTML;
textArray = b[i].textContent.split(" ");
for (var j = 0; j < textArray.length; j++) {
if (textArray[j] !== "" && validURL(textArray[j])) {
ahref = document.createElement('a');
ahref.href = (/^(http:\/\/|https:\/\/)/).test(textArray[j]) ? textArray[j] : "http://" + textArray[j];
ahref.innerText = textArray[j];
ahref.className = "easyURLparse";
textArray[j] = ahref;
}
newHTML+= textArray[j].outerHTML ? textArray[j].outerHTML + " " : textArray[j] + " ";
}
var div = document.createElement('div');
div.innerHTML = newHTML;
newHTML = "";
b[i].parentNode.insertBefore(div, b[i]);
b[i].parentNode.removeChild(b[i].nextSibling);
}
}
function validURL(str) {
var pattern = new RegExp("([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+#)?([a-zA-Z0-9.-]+\\.[A-Za-z]{2,4})(:[0-9]+)?(/.*)?");
if (!pattern.test(str)) {
return false;
} else {
return true;
}
}
Testing Code
Just need to figure out the undefined and why it's adding it
this regexp will do the job
exp = /href="(\b(https?|ftp|file):\/\/[\-A-Z0-9+&##\/%?=~_|!:,.;]*[\-A-Z0-9+&##\/%=~_|])"/ig;
var a = document.querySelectorAll('.post');
var b = a[0].childNodes;
var textArray;
var ahref;
for (i = 0; i < b.length; i++) {
var exp = /(\b(https?|ftp|file):\/\/[\-A-Z0-9+&##\/%?=~_|!:,.;]*[\-A-Z0-9+&##\/%=~_|])/ig;
if (b[i].nodeType === 3) {
var newHTML;
if (validURL(b[i].textContent)) {
textArray = b[i].textContent.split(" ");
for (var j = 0; j < textArray.length; j++) {
if (textArray[j] !== undefined && textArray[j] !== "" && validURL(textArray[j]) && textArray[j] !== null) {
ahref = document.createElement('a');
ahref.href = (/^(http:\/\/|https:\/\/)/).test(textArray[j]) ? textArray[j] : "http://" + textArray[j];
ahref.innerText = textArray[j];
ahref.className = "easyURLparse";
textArray[j] = ahref;
}
newHTML += textArray[j].outerHTML ? textArray[j].outerHTML + " " : textArray[j] + " ";
}
var div = document.createElement('div');
div.innerHTML = newHTML;
div.className = "easyDiv";
b[i].parentNode.insertBefore(div, b[i]);
b[i].parentNode.removeChild(b[i].nextSibling);
}
newHTML = "";
}
}
function validURL(str) {
var pattern = new RegExp("([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+#)?([a-zA-Z0-9.-]+\\.[A-Za-z]{2,4})(:[0-9]+)?(/.*)?");
if (!pattern.test(str)) {
return false;
} else {
return true;
}
}
By taking the textNodes and splitting them into an array I can then change the url into an html element. Then taking the array elements seeing if there is outerHTML or not then placing it in a new string and replacing that textNode now with a workable link.
Working example

JavaScript Tag Cloud with IBM Cognos - IE is null or not an object

I followed a tutorial/modified the code to get a javascript tag cloud working in IBM Cognos (BI software). The tag cloud works fine in FireFox but in Internet Explorer I get the error:
"Message: '1' is null or not an object"
The line of code where this is present is 225 which is:
var B = b[1].toLowerCase();
I have tried many different solutions that I have seen but have been unable to get this working correctly, the rest of the code is as follows:
<script>
// JavaScript Document
// ====================================
// params that might need changin.
// DON'T forget to include a drill url in the href section below (see ###) if you want this report to be drillable
var delimit = "|";
var subdelimit = "[]"; // change this as needed (ex: Smith, Michael[]$500,000.00|)
var labelColumnNumber = 0; // first column is 0
var valueColumnNumber = 1;
var columnCount = 2; // how many columns are there in the list?
// ====================================
/*
function formatCurrency(num) {
num = num.toString().replace(/\$|\,/g,'');
if(isNaN(num))
num = "0";
sign = (num == (num = Math.abs(num)));
num = Math.floor(num*100+0.50000000001);
cents = num%100;
num = Math.floor(num/100).toString();
if(cents<10)
cents = "0" + cents;
for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
num = num.substring(0,num.length-(4*i+3))+','+ num.substring(num.length-(4*i+3));
return (((sign)?'':'-') + '$' + num + '.' + cents);
}
*/
function formatCurrency(num) {
num = num.toString().replace(/\$|\,/g,'');
if(isNaN(num))
num = "0";
for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
num = num.substring(0,num.length-(4*i+3))+','+ num.substring(num.length-(4*i+3));
return ( num );
}
function filterNum(str) {
re = /\$|,|#|#|~|`|\%|\*|\^|\&|\(|\)|\+|\=|\[|\-|\_|\]|\[|\}|\{|\;|\:|\'|\"|\<|\>|\?|\||\\|\!|\$|/g;
// remove special characters like "$" and "," etc...
return str.replace(re, "");
}
table = document.getElementById("dg");
if ( table.style.visibility != 'hidden'){ //only for visible
/*alert('Visible');*/
tags = document.getElementById("dg").getElementsByTagName("SPAN");
txt = "";
var newText = "a";
for (var i=columnCount; i<tags.length; i++) {
/*
valu = filterNum(tags[i+valueColumnNumber].innerHTML);
txt += valu;
txt += subdelimit+tags[i+labelColumnNumber].innerHTML+delimit;
i = i+columnCount;
*/
if(i%2!=0){
var newValue = filterNum(tags[i].innerHTML);
}else var newName =tags[i].innerHTML;
if((i>2) & (i%2!=0)){
newText = newText+newValue+subdelimit+newName+delimit;
if(typeof newText != 'undefined'){
txt = newText;
txt = txt.substr(9);
/* alert(txt);*/
}
}
}
}/*else alert ('Hidden');*/
function getFontSize(min,max,val) {
return Math.round((150.0*(1.0+(1.5*val-max/2)/max)));
}
function generateCloud(txt) {
//var txt = "48.1[]Google|28.1[]Yahoo!|10.5[]Live/MSN|4.9[]Ask|5[]AOL";
var logarithmic = false;
var lines = txt.split(delimit);
var min = 10000000000;
var max = 0;
for(var i=0;i<lines.length;i++) {
var line = lines[i];
var data = line.split(subdelimit);
if(data.length != 2) {
lines.splice(i,1);
continue;
}
data[0] = parseFloat(data[0]);
lines[i] = data;
if(data[0] > max)
max = data[0];
if(data[0] < min)
min = data[0];
}lines.sort(function (a,b) {
var A = a[1].toLowerCase();
var B = b[1].toLowerCase();
return A>B ? 1 : (A<B ? -1 : 0);
});
var html = "<style type='text/css'>#jscloud a:hover { text-decoration: underline; }</style> <div id='jscloud'>";
if(logarithmic) {
max = Math.log(max);
min = Math.log(min);
}
for(var i=0;i<lines.length;i++) {
var val = lines[i][0];
if(logarithmic) val = Math.log(val);
var fsize = getFontSize(min,max,val);
dollar = formatCurrency(lines[i][0]);
html += " <a href='###Some drillthrough url which includes the param "+lines[i][1]+"' style='font-size:"+fsize+"%;' title='"+dollar+"'>"+lines[i][1]+"</a> ";
}
html += "</div>";
var cloud = document.getElementById("cloud");
cloud.innerHTML = html;
var cloudhtml = document.getElementById("cloudhtml");
cloudhtml.value = html;
}
function setClass(layer,cls) {
layer.setAttribute("class",cls);
layer.setAttribute("className",cls);
}
function show(display) {
var cloud = document.getElementById("cloud");
var cloudhtml = document.getElementById("cloudhtml");if(display == "cloud") {
setClass(cloud,"visible");
setClass(cloudhtml,"hidden");
}
else if(display == "html") {
setClass(cloud,"hidden");
setClass(cloudhtml,"visible");
}
}
generateCloud(txt);
</script>
Any help or explanations is much appreciated
Sorry, I'm not seeing where a[] and b[] are defined, is this done elsewhere? Firefox and IE may be responding differently to the problem of an undefined array.

Categories