I am doing an export to CSV functionality on my website. The data are in spanish so there will be alot of accented characters in there, and one example of this problem is the header "Año" (year) but on excel it shows as "Año".
Here is my export code using javascript:
HTML
Export
Download Now
JS
$(document).on('click', '#export-btn', function(e) {
var _this = $(this);
_this.attr('disabled',true);
var datenow = new Date();
datenow = datenow.getTime();
var exportdata = ConvertToCSV(exportdata);
$('#download').attr("href", "data:text/csv;charset=utf8," + encodeURIComponent(exportdata) );
$('#download').attr("download", "InTrack-Report-"+datenow+".csv");
$('#download').show(); //show download button
_this.attr('disabled',false);
});
here is the ConvertToCSV function, I added sep=; to make excel recognize the semicolon as delimiters.
function ConvertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = 'sep=;\r\n'; //tell excel that we used semicolon as separator
//header
var line = '';
for (var i = 0; i < array.Fields.length; i++) {
if (line != '') line += ';'
line += array.Fields[i]['Title'];
}
str += line + '\r\n';
//rows
for (var i = 0; i < array.Rows.length; i++) {
var line = '';
for (var index in array.Rows[i]) {
if (line != '') line += ';'
line += array.Rows[i][index];
}
str += line + '\r\n';
}
return str;
}
UPDATE:
I found a way to display the accented letters properly by following the solution here. But I had to remove the sep=; which is important as it separates my data by semicolon. Is there a way to add both the BOM and the sep=; at the top? If so, how? Because it seems like I can only use one.
So instead of str='sep=;\r\n' it is now str='\uFEFF sep=;\r\n'
if you get an error with the ASCII in the creation of file.csv, try adding the BOM first.
var BOM = "\uFEFF";
return BOM + str;
and then crate the file headers with the data: "text/csv;charset=utf-8"
instead of utf8 (without - )
Use escape at place of encodeURI and add "sep=;\n" before string and allow it to escape as well
Sample code
var csvString = "sep=;\n" + csvRows.join("\n");
var a = document.createElement('a');
a.href = 'data:attachment/csv;charset=UTF-8,%EF%BB%BF' + escape(csvString);
I am trying to add values to a textbox when looping through an array when checking checkboxes but as it is at the moment getting undefined.
Advice perhaps as to why the values are 'undefined'
var txtBoxValues = [];
$(document).on("click", "input[name=chkRelatedTopics]", function () {
var nameAdminUser = $(this).val();
var txtBox = document.getElementById("txtTraningTopics");
txtBox.value = '';
txtBoxValues.push(nameAdminUser);
for (var i in txtBoxValues) {
var str = txtBoxValues[i].value;
txtBox.value += str + '; ';
}
});
nameAdminUser is already a string, so don't take .value from it.
You could replace
var str = txtBoxValues[i].value;
with
var str = txtBoxValues[i];
But instead of using this loop, and assuming you don't want, as I suppose, the last ";", you could also do
txtBox.value = txtBoxValues.join(';');
nameAdminUser seems to be a String and in your for loop you expect an object. What if you simply do:
for (var i in txtBoxValues) {
var str = txtBoxValues[i];
txtBox.value += str + '; ';
}
I have the following code, which should split this string #266##271##295# into this
266
271
295
and append it to the same container where it came from: .groups
$('.groups').each(function(){
var str = $(this).html();
if (str.substring(0, 1) == '#') {
str = str.substring(1); // Remove first #
}
if(str.substring(str.length-1, str.length) == '#'){
str = str.substring(0, str.length-1); // Remove last #
}
str = str.split(/[##]+/);
$(this).empty(); // empty the groups container
$.each(str, function(index, val){
alert(val);
var html = '' + val + ''
$(html).appendTo(this);
});
});
My problem (i think) is the line $(html).appendTo(this);
i somehow need to add it to the previous each().
How can I do this. Or am I moving in the wrong direction with this code?
I think you made this way too complicated, just do this:
var str = $(this).html();
var parts = str.split("#");
var html = "";
for (var i = 0; i < parts.length; i++) {
html += '' + parts[i] + '';
}
$(this).append(html);
Something like this?
$('.groups').each(function(){
var str = $(this).html();
if (str.substring(0, 1) == '#') {
str = str.substring(1); // Remove first #
}
if(str.substring(str.length-1, str.length) == '#'){
str = str.substring(0, str.length-1); // Remove last #
}
str = str.split(/[##]+/);
$(this).empty(); // empty the groups container
var target = $(this);
$.each(str, function(index, val){
alert(val);
var html = '' + val + ''
$(html).appendTo(target);
});
});
I added the var target = $(this) outside your second loop as a reference that you can use inside your second loop.
You do need to be mindful of the leading and trailing #'s, but you can easily trim them while you split with a clever regex. When you use $.each to iterate over an array, the this reference no longer refers to your original context but to the current item. Constructing the item's markup and concatenating to a string which you insert outside of the loop will not only get around this, but also provide better performance since you will only be doing one DOM insertion.
$('.groups').each(function(){
var str = $(this).html();
str = str.replace(/^#+|#+$/g, ''); // trim leading and trailing #
var links = str.split("#");
var markup = '';
$.each(links, function(){
markup += '' + this + "\n";
});
$(markup).appendTo(this);
});
This is a follow up question to my question about Setting the CSS of code if it contains a reserved word.
What I am trying to do: If some code has quotes or double quotes, I want to set the color of the font to red and bold. Ex. System.out.println( "Hello world" ); should set "Hello world" to red.
What's wrong: Despite my best efforts, I can't seem to get my control statements to work properly (at least I think that's the issue). It sets the first double quote and beyond to red, but when I tell it to stop when a word equals anyword" or anyword' it sets the rest of the code in the block to red.
HTML
<html>
<body>
<code id="java">
public static void main(String[] args)<br>
{
<pre> int i = 120; </pre><br>
<pre> // Displays a message in the console </pre>
<pre> // This is a test </pre>
<pre> System.out.println( "Hello Big World!" );</pre>
}
</code>
</body>
</html>
CSS
.quotes
{
font-weight: bold;
color: #E01B1B;
}
jQuery
$(document).ready(function() {
var code = $("#java").html(); // Get the code
var split = code.split(' '); // Split up each element
var chkQ = 0; // Check for quotes
var chkC = 0; // Check until end of comment line
// Set the CSS of reserved words, digits, strings, and comments
for (var j = 0; j < split.length; j++) {
// Check to see if chkQ is set to true
if (chkQ == 1) {
// If the element matches (anyword") or (anyword'), then set
// flag to false and continue checking the rest of the code.
// Else, continue setting the CSS to .quotes
if (split[j].match(/."/) || split[j].match(/.'/)) {
split[j] = '<span class="quotes">' + split[j] + '</span>';
chkQ = 0;
} else {
split[j] = '<span class="quotes">' + split[j] + '</span>';
}
}
...
} else if (chkQ == 0 && chkC == 0) {
...
// If the element matches a ("anyword) or ('anyword)...
} else if (split[j].match(/"./) || split[j].match(/'./)) {
split[j] = '<span class="quotes">' + split[j] + '</span>';
chkQ = 1;
} ...
}
}
// Join all the split up elements back together!
$("#java").html(split.join(' '));
});
Question: Is this just simply an issue with my regex, control blocks or something completely different?
Why split the string up when you can perform a simple global regex find and replace:
<script type="text/javascript">
$(document).ready(function(){
//cache the element
el = $('#java');
//get the HTML contained within the cached element
code = el.html();
//return the code having executed the replace method, regex explained:
/*
([^\w]{1}) -> look for a single character that is not an alpha character
(["']) -> then look for either a single quote or double quote
(.*?) -> then look any character, but don't be greedy
(\2) -> then look for what was found in the second group - " or '
([^\w]{1}) -> and finally look for a single character that is not an alpha character
*/
code = code.replace(/([^\w]{1})(["'])(.*?)(\2)([^\w]{1})/gm,
//execute an anonymous callback, passing in the result for every match found
function(match, $1, $2, $3, $4, $5, offset, original) {
//construct the replacement
str = $1 + '<span class="quotes">' + $2 + $3 + $4 + '</span>' + $5;
//return the replacement
return str;
});
//replace the existing HTML within the cached element
el.html(code);
});
</script>
Edit: Just updated it to accommodate nested quotes.
I don't know all your requirements, but it seems that your single quote could get a bit complicated.
I've set up a demonstration that works (updated link to include nested quotes).
I do not guarantee it is bug free. It does the replacement in two stages, first for double quotes, then for single, trying to weed out potential apostrophes (note in the code below the filters for apostrophes are based off common following letters--not sure how many you might practically need, if any).
Javascript
$(document).ready(function() {
var code = $("#java").html(); // Get the code
var split = code.split('\"'); // Split up each element at the "
// Set the CSS of reserved words, digits, strings, and comments
for (var j = 0; j < split.length - 1; j++) {
if (j%2 == 0) { //if first, add beginning
split[j] = split[j] + '<span class="quotes">"';
} else {//if second, add ending
split[j] = split[j] + '"</span>';
}
}
// Join all the split up elements back together!
$("#java").html(split.join(""));
code = $("#java").html(); // Get the code
split = code.split('\''); // Split up each element at the '
var openQ = 1;
var sub1;
var sub2;
for (var j = 0; j < split.length - 1; j++) {
sub1 = split[j+1].substr(0,2); //checking for a contraction of 's
sub2 = split[j+1].substr(0,3); //checking for a contraction of 'll
if(sub1 != "s " && sub2 != "ll ") {
if (openQ) { //if first, add beginning
split[j] = split[j] + '<span class="quotes">\'';
openQ = 0;
} else {//if second, add ending
split[j] = split[j] + '\'</span>';
openQ = 1;
}
}
else {//add apostrophe back
split[j] = split[j] + '\'';
}
}
$("#java").html(split.join(""));
});
Here's a pure JavaScript version:
id= id of element with quotes
classid= class to add to the quotes
function quotes(id,classid) {
var code = document.getElementById(id).innerHTML;
var split = code.split('\"');
for (var j = 0; j < split.length - 1; j++) {
if (j%2 == 0) {
split[j] = split[j] + '<span class='+classid+'>"';
} else {
split[j] = split[j] + '"</span>';
}
}
document.getElementById(id).innerHTML = split.join("");
code = document.getElementById(id).innerHTML;
split = code.split('\'');
var openQ = 1;
var sub1;
var sub2;
for (var j = 0; j < split.length - 1; j++) {
sub1 = split[j+1].substr(0,2);
sub2 = split[j+1].substr(0,3);
if(sub1 != "s " && sub2 != "ll ") {
if (openQ) {
split[j] = split[j] + '<span class='+classid+'>\'';
openQ = 0;
} else {
split[j] = split[j] + '\'</span>';
openQ = 1;
}
}
else {
split[j] = split[j] + '\'';
}
}
document.getElementById(id).innerHTML = split.join("");
}
String.prototype.Text2Html = function (){
var div = document.createElement('div');
div.appendChild(document.createTextNode(this))
encoded=div.innerHTML;
div.remove();
return encoded
}
String.prototype.colorTheQuotes = function(){
var re = /(?:<span style=|)(?:(?:"[^"]*")|(?:'[^']*'))/gm,
text = this.Text2Html(),
output = text,
tour = 0,
slen = 27;
while ((match = re.exec(text)) != null) {
if(match[0].startsWith("<span")) continue
output=output.slice(0,match.index+tour*slen)+'<span class="quote">'+output.slice(match.index+tour*slen,match.index+match[0].length+tour*slen)+"</span>"+output.slice(match.index+match[0].length+tour*slen);tour++
}
return output
}
element=document.getElementById("color")
document.addEventListener("readystatechange",(e)=>{
element.innerHTML=element.innerText.colorTheQuotes();
})
.quote{
color: red;
}
<span>System.out.println( "Hello world" );</span><br>
<span id="color">System.out.println( "Hello world" );</span>
I am new to jQuery and Javascript. I have to create select->option drop down control with client side jQuery/Javascripting. These drop downs are having their options from array and i have to create as many drop down as the array items. Please below two functions written, they are not drawing many drop downs but only one.
<script type="text/javascript">
// program inputs
var format1Fields = ",RepID,RetailOutlet,Address,Information,City,State,ZipCode, Demographic,Bullet,Date,Note1,Note2,Note3,Note4,Note5,AssignTask1,AssignTask2,AssignTask3,AssignTask4,LiquorPresence,PhotoLink1,Description1,PhotoLink2,Description2,PhotoLink3,Description3,PhotoLink4,Description4,PhotoLink5,Description5,PhotoLink6,Description6,PhotoLink7,Description7,PhotoLink8,Description8,PhotoLink9,Description9,PhotoLink10,Description10,PhotoLink11,Description11,PhotoLink12,Description12,Videolink1,Videodescription1,Videolink2,Videodescription2,Videolink3,Videodescription3,Videolink4,Videodescription4,POSInstalled1, POSQuantity1,POSInstalled2,POSQuantity2,POSInstalled3,POSQuantity3,POSInstalled4,POSQuantity4,POSInstalled5,POSQuantity5, POSInstalled6,POSQuantity6,POSInstalled7,POSQuantity7,POSInstalled8,POSQuantity8,POSInstalled9,POSQuantity9,POSInstalled10, POSQuantity10,POSInstalled11,POSQuantity11,POSInstalled12,POSQuantity12,Project,Visit,";
var outputFieldsString = "date visited,Mapping link,Date,RepID,Project,RetailOutLet,Address,City,State,Information,Demographic,Bullet,Note1,Note2,Note3,Note4,Note5,AssignTask1,AssignTask2,Assigntask3,AssignTask4,LiquorPresence,PhotoLink1,Picture01,Description1,PhotoLink2,Picture02,Description2,PhotoLink3,Picture03,Description3,PhotoLink4,Picture04,Description4,PhotoLink5,Picture05,Description5,PhotoLink6,Picture06,Description6,PhotoLink7,Picture07,Description7,PhotoLink8,Picture08,Description8,PosInstalled1,MC Cold Box Sticker,PosInstalled2,MC Poster 12 X 18,PosInstalled3,MC Poster 18 X 24,PosInstalled4,MC Poster 24 X 36,PosInstalled5,MC Case Cards,PosInstalled6,MC Standees,PosInstalled7,GM Poster 11 X 17,PosInstalled8,GM Poster 18 X 24,PosInstalled9,GM Recipe Table Tent,Photolink9,Description9,Photolink10,Description10,Photolink11,Description11,Photolink12,POSInstalled10,GM Shelf talker,POSInstalled11,GM Case Cards,POSInstalled12,GM Standees,Picture09,Picture10,Picture11,Picture12,Description12";
var outputDelimiter = ",";
var inputFieldList = new Array();
var outputFieldList = new Array();
$(document).ready(function(){
//$('#inputfields').val(trimOnSides(format1Fields.replace(' /g',''),","));
$('#inputfields').val(trimOnSides(format1Fields,","));
// start mapping click event
$('#start_mapping').click(function(){
var inputFieldString = $('#inputfields').val();
var inputDelimiter = $('#delimiter option:selected').val();
// input field validation
if(inputFieldString == ""){
alert("Please provide Input Fields header line having delimeter to identify the field names!");
$('#inputfields').focus();
return false;
}
// delimiter validation
if(inputDelimiter == "0"){
alert("Please select the correct delimiter that is matches with the seperating delimiter of the Input Fields!");
return false;
}
// Load input fields item array
inputFieldList = getFieldsList(inputFieldString,inputDelimiter);
if(inputFieldList.length==0){
alert("Problem transforming Input Field data into list of items for mapping");
return false;
}
// Load output fields item array
outputFieldList = getFieldsList(outputFieldsString,outputDelimiter);
if(outputFieldList.length==0){
alert("Problem transforming Output Field data into list of items for mapping");
return false;
}
// print field list item in HTML <ol>
getFormListItems(inputFieldList);
//getDropDownList('waqas','aiseha',inputFieldList);
});
});
// ###### HELPER FUNCTIONS #######
// helper to generate form of drop down
function getFormListItems(fieldListItems){
if((fieldListItems instanceof Array) && (fieldListItems.length>0)){
var list = $('#mappingitems').append('<ul></ul>').find('ul');
for(i=0; i<=fieldListItems.length-1; i++){
list.append('<li>');
list.append(getDropDownList(fieldListItems[i],fieldListItems[i],fieldListItems));
list.append('</li>');
//list.append('<li>'+fieldListItems[i]+'</li>');
//alert(i);
}
}
}
function getDropDownList(name, id, optionList) {
var combo = $("<select></select>").attr("name", name);
$.each(optionList, function (i, el) {
combo.append("<option>" + el + "</option>");
});
return combo;
// OR
//$("#SELECTOR").append(combo);
}
// helper split based string array generators
function getFieldsList(fieldsString, delimiter){
var returnList = new Array();
//alert(fieldsString);
// validating the arguments and their data type
if((fieldsString.length > 0) && (delimiter.length>0)){
returnList = fieldsString.split(delimiter);
return returnList;
}else{
alert('Problem in function arguments');
}
}
// helper string functions
function trimOnSides(str, chars) {
return ltrim(rtrim(str, chars), chars);
}
function ltrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
function rtrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}
</script>
this is the call to the function: getFormListItems(inputFieldList);
inputFieldList can contain Apple, Orange, Banana, Mango
Please help
thanks
Waqas
This will create the drop downs on the fly:
function getDropDownList(name, id, optionList) {
var combo = $("<select></select>").attr("id", id).attr("name", name);
$.each(optionList, function (i, el) {
combo.append("<option>" + el + "</option>");
});
return combo;
// OR
$("#SELECTOR").append(combo);
}