passing string values with special characters to a function Javascript - javascript

I have a function that requires full name as an input, this name can have hyphens,apotrohpe,comma etc.
function AddOtherRefDoc(name, number) {
var remove = "<a \href='javascript:void(0);' onclick='removeRefDoctor(this,'"+name+"',"+number+");'\">Remove</a>";
var html = "<li><b> Referral Doctor: </b>"+name+"<b>, Referral No: </b>"+number+ " " +remove+" <input type='text' name='ref_docs' value='"+name+"'></input><input type='text' name='ref_nos' value='"+number+"'></input></li>";
jQuery(opener.document).find("#r_docs").append(html);
}
The way I'm passing name to removeRefDoctor(), it's not working. How can I wrap this name into one string so that the function can accept this value.
Thanks a lot for ur help.

It'd be easier for you to read and fix if you'd reimplement it like this for both variables:
var remove = $("<a/>")
.attr('href', 'javascript:void(0);')
.click(function() {
removeRefDoctor(this,name,number);
})
.text('Remove');

I see some errors on the second line.
Use this
var remove = "Remove";

You are using single quotes to quote the onclick attribute and to quote the name value passed in the function. This closes your onclick attribute early. You may also have single quotes in your name value. You'll need to use double quotes around your name value and also escape any quotes to avoid html parsing issues. Similarly, you'll need to escape quotes where you are using name as the value for your <input />
var attrName = name.replace(/'/g, ''');
var jsName = attrName.replace(/"/g, '\\"');
Use it in your function like this:
function AddOtherRefDoc(name, number) {
var attrName = name.replace(/'/g, ''');
var jsName = attrName.replace(/"/g, '\\"');
var remove = "<a \href='javascript:void(0);' onclick='removeRefDoctor(this,\""+jsName +"\","+number+");'\">Remove</a>";
var html = "<li><b> Referral Doctor: </b>"+name+"<b>, Referral No: </b>"+number+ " " +remove+" <input type='text' name='ref_docs' value='"+attrName+"'></input><input type='text' name='ref_nos' value='"+number+"'></input></li>";
jQuery(opener.document).find("#r_docs").append(html);
}
That's the answer to why your code isn't working as you expect. All that being said, I'd go with Mike Thompson's approach. That makes a lot more sense and solves a lot of problems for you.

Related

How to escape the ampersand in "$quote;"

I use a kendo template in jsp:
<assd:column has-tooltip="false" width="150px" name="groupName"
template="<span data-link-value='{gId:"#:id#", gName:"#:schoolNameSafe# группа #:groupNameSafe# (#:groupType#)", gType:"#:groupTypeId#", imported:"#:hasLicenses#"}'>#:groupName#</span>"
>Group</assd:column>
And also a JavaScript logic like:
var template = kendo.template(this.rowLinkTemplate);
var fieldData = {};
var dataLinkValue = $("[data-link-value]", arg.currentTarget).attr("data-link-value");
var link = template(eval("(" + dataLinkValue + ")"));
document.location = link;
I have an input string for gName: "CDS "Car Driving School""
The problem is in ampersand in $quot; which is perceived by browser as a delimiter and it turns out that CDS goes to the gName variable, but everything after is considered a key because of the ampersand.
Is it possible to escape the ampersand in $quot;?
Is there any reason you couldn't just use " normally and escape it (rather than encode it)? e.g.
<assd:column has-tooltip="false" width="150px" name="groupName"
template="<span data-link-value='{gId:\"#:id#\", gName:\"#:schoolNameSafe# группа #:groupNameSafe# (#:groupType#)\", gType:\"#:groupTypeId#\", imported:\"#:hasLicenses#\"}'>#:groupName#</span>"
>Group</assd:column>
Disclaimer: I don't know much about kendo so it is entirely possible that there is a reason that this can't be done that I'm unaware of.

Replace HTML Comment along with string variable

In my project I have some html with comments surrounding text so I can find the text between particular comments and replace that text whilst leaving the comments so I can do it again.
I am having trouble getting the regex to work.
Here is an html line I am working on:
<td class="spaced" style="font-family: Garamond,Palatino,sans-serif;font-size: medium;padding-top: 10px;"><!--firstname-->Harrison<!--firstname--> <!--lastname-->Ford<!--lastname--> <span class="spacer"></span></td>
Now, here is the javascript/jquery that I have at the moment:
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
currentTemplate = $("#gentextCodeArea").text(); //fetch the text
var tokenstring = "<!--" + thistoken + "-->"
var pattern = new RegExp(tokenstring + '\\w+' + tokenstring,'i');
currentTemplate.replace(pattern, tokenstring + thisval + tokenstring);
$("#gentextCodeArea").text(currentTemplate); //put the new text back
I think I'm pretty close, but I don't have the regex right yet.
The regex ought to replace the firstname with whatever is entered in the textbox for $thisval (method is attached to keyup procedure on textbox).
Using plain span tags instead of comments would make things easier, but either way, I would suggest not using regular expressions for this. There can be border cases that may lead to undesired results.
If you stick with comment tags, I would iterate over the child nodes and then make the replacement, like so:
$("#fname").on("input", function () {
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
var between = false;
$("#gentextCodeArea").contents().each(function () {
if (this.nodeType === 8 && this.nodeValue.trim() === thistoken) {
if (between) return false;
between = true;
} else if (between) {
this.nodeValue = thisval;
thisval = '';
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
New first name: <input id="fname">
<div id="gentextCodeArea">
<!--firstname-->Harrison<!--firstname-->
<!--lastname-->Ford<!--lastname-->
<span class="spacer"></span></div>
What went wrong in your code
By using text() you don't get the comment tags. To get those, you need to use html() instead
replace() does not mutate the variable given in the first argument, but returns the modified string. So you need to assign that back to currentTemplate
It would be better to use [^<]* instead of \w+ for matching the first name, as some first names have non-letters in them (hyphen, space, ...), and it may even be empty.
Here is the corrected version, but I insist that regular expressions are not the best solution for such a task:
$("#fname").on("input", function () {
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
currentTemplate = $("#gentextCodeArea").html(); //fetch the html
var tokenstring = "<!--" + thistoken + "-->"
var pattern = new RegExp(tokenstring + '[^<]*' + tokenstring,'i');
currentTemplate = currentTemplate.replace(pattern, tokenstring + thisval + tokenstring);
$("#gentextCodeArea").html(currentTemplate); //put the new text back
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
New first name: <input id="fname">
<div id="gentextCodeArea">
<!--firstname-->Harrison<!--firstname-->
<!--lastname-->Ford<!--lastname-->
<span class="spacer"></span></div>
here is a function which will generate an appropriate Regular expression:
function templatePattern(key) {
return new RegExp(`<!--${key}-->(.*?)<!--${key}-->`);
}
the (.*?) means "match as little as possible," so it will stop at the first instance of the closing tag.
Example:
'<!--firstname-->Harrison<!--firstname--> <!--lastname-->Ford<!--lastname-->'
.replace(templatePattern('firstname'), 'Bob')
.replace(templatePattern('lastname'), 'Johnson') // "Bob Johnson"
$(function(){
function onKeyUp(event)
{
if(event.which === 38) // if key press was the up key
{
$('.firstname_placeholder').text($(this).val());
}
}
$('#firstname_input').keyup(onKeyUp);
});
input[type=text]{width:200px}
<input id='firstname_input' type='text' placeholder='type in a name then press the up key'/>
<table>
<tr>
<td ><span class='firstname_placeholder'>Harrison</span> <span class='lastname_placeholder'>Ford</span> <span class="spacer"></span></td>
</tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

How to add custom image tag to pagedown?

I'm attempting to duplicate the original img tag's functionality in custom img tag that will be added to the pagedown converter.
e.g I'm copy the original behavior:
![image_url][1] [1]: http://lolink.com gives <img src="http://lolink.com">
into a custom one:
?[image_url][1] [1]: http://lolink.com gives <img class="lol" src="http://lolink.com">
Looking at the docs the only way to do this is through using the preblockgamut hook and then adding another "block level structure." I attempted doing this and got an Uncaught Error: Recursive call to converter.makeHtml
here's the code of me messing around with it:
converter.hooks.chain("preBlockGamut", function (text, dosomething) {
return text.replace(/(\?\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, function (whole, inner) {
return "<img src=" + dosomething(inner) + ">";
});
});
I'm not very experienced with hooks and everything so what would I do to fix it? Thanks.
UPDATE: found out that _DoImages runs after prespangamut, will use that instead of preblockgamut
Figured it out! The solution is very clunky and involves editing the source code because I am very bad at regex and the _DoImage() function uses a lot of internal functions only in the source.
solution:
All edits will be made to the markdown.converter file.
do a ctrl+f for the _DoImage function, you will find that it is named in two places, one in the RunSpanGamut and one defining the function. The solution is simple, copy over the DoImage function and related stuff to a new one in order to mimic the original function and edit it to taste.
next to DoImage function add:
function _DoPotatoImages(text) {
text = text.replace(/(\?\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writePotatoImageTag);
text = text.replace(/(\?\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writePotatoImageTag);
return text;
}
function writePotatoImageTag(wholeMatch, m1, m2, m3, m4, m5, m6, m7) {
var whole_match = m1;
var alt_text = m2;
var link_id = m3.toLowerCase();
var url = m4;
var title = m7;
if (!title) title = "";
if (url == "") {
if (link_id == "") {
link_id = alt_text.toLowerCase().replace(/ ?\n/g, " ");
}
url = "#" + link_id;
if (g_urls.get(link_id) != undefined) {
url = g_urls.get(link_id);
if (g_titles.get(link_id) != undefined) {
title = g_titles.get(link_id);
}
}
else {
return whole_match;
}
}
alt_text = escapeCharacters(attributeEncode(alt_text), "*_[]()");
url = escapeCharacters(url, "*_");
var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
title = attributeEncode(title);
title = escapeCharacters(title, "*_");
result += " title=\"" + title + "\"";
result += " class=\"p\" />";
return result;
}
if you look at the difference between the new _DoPotatoImages() function and the original _DoImages(), you will notice I edited the regex to have an escaped question mark \? instead of the normal exclamation mark !
Also notice how the writePotatoImageTag calls g_urls and g_titles which are some of the internal functions that are called.
After that, add your text = _DoPotatoImages(text); to runSpanGamut function (MAKE SURE YOU ADD IT BEFORE THE text = _DoAnchors(text); LINE BECAUSE THAT FUNCTION WILL OVERRIDE IMAGE TAGS) and now you should be able to write ?[image desc](url) along with ![image desc](url)
done.
The full line (not only the regex) in Markdown.Converter.js goes like this:
text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeImageTag);
so check the function writeImageTag. There you can see how the regex matching text is replaced with a full img tag.
You can change the almost-last line before its return from
result += " />";
to
result += ' class="lol" />';
Thanks for the edit to the main post.
I see what you mean now.
It is a bit weird how it uses empty capture groups to specify tags, but if it works, it works.
It looks like you would need to add on an extra () onto the regex string, then specify m8 as a new extra variable to be passed into the function, and then specify it as class = m8; like the other variables at the top of the function.
Then where it says var result =, instead of class =\"p\" you would just put class + title=\"" + .......

Prefix article keyword with date(Y-m-d)

In the CMS I am building, record names have to be unique (they are URL keywords). In order to achieve this with blog posts, I am attempting to prefix blog post titles with date("Y-m-d") in PHP.
I have a "title" input text field, in which the title is entered, a "keyword" text field which automatically "slugs" the title in order to turn it into a URL keyword.
I'm having trouble figuring out how to prefix the slugged title with the date.
Here's the code:
<input name="title" type="text" id="title" />
<input name="keyword" type="text" id="slug" />
<script type="text/javascript">
$(document).ready(function(){
$("#title").slug();
});
</script>
This part works. The title successfully turns into a keyword with dashes for spaces, eliminating special characters, etc.
I tried including the date by adding a hidden field with the date as the value and accessing its value with the getElementById function. I attempted to rework the javascript to concatenate the slugged title with the date:
<input type = "hidden" id = "postdate" value = "<?php echo date("Y-m-d"); ?>-" />
<script type="text/javascript">
$(document).ready(function(){
var getDate = document.getElementById('postdate');
var doSlug = $("#title").val();
var slugString = getDate + doSlug;
$("slugString").slug();
});
</script>
But I'm obviously not working properly with the javascript.
The output I'm after would be: "2013-10-09-title-of-this-blog-post"
Where am I going wrong?
Working Fiddle
I suggest you to do a little tweak to the plugin to be able to do what you want.
As you can see in the feedle above i add two new configuration parameters
prepend: null, // String to be prepended the sluged string
append: null // String to be appended the sluged string
and on the makeSlug function i just add this two conditionals
if(typeof settings.append === 'string')
slug = slug + '-' + settings.append;
if(typeof settings.prepend === 'string')
slug = settings.prepend + '-' + slug;
Now you can prepend or append a string to the slugfy version of your string
$("#title").slug({
prepend: '2010-10-13',
append: 'YAYY'
});
If you decide to use this approach, here is how to use with your html
$(document).ready(function(){
$("#title").slug({
prepend: $('#postdate').val()
});
});
How about:
$(document).ready(function(){
var getDate = $('#postdate').val(); // get the value of the postdate id, not the element.
var doSlug = $("#title").val();
var slugString = getDate + "-" + doSlug;
$('#title').val(slugString);
$('#title').slug(); // if needed.
});
The jQuery slug() function is changing the input value to be "slugged". You can't set it to "slugString", because that's a variable, not a dom element. If necessary, you can "reslug" the input value after setting it with val().
Edited to fix the getDate variable issue that #Oswaldo Acauan picked up

Pass variable in document.getElementByid in javascript

I have a variable account_number in which account number is stored. now i want to get the value of the element having id as account_number. How to do it in javascript ?
I tried doing document.getElementById(account_number).value, but it is null.
html looks like this :
<input class='transparent' disabled type='text' name='113114234567_name' id='113114234567_name' value = 'Neeloy' style='border:0px;height:25px;font-size:16px;line-height:25px;' />
and the js is :
function getElement()
{
var acc_list = document.forms.editBeneficiary.elements.bene_account_number_edit;
for(var i=0;i<acc_list.length;i++)
{
if(acc_list[i].checked == true)
{
var account_number = acc_list[i].value.toString();
var ben_name = account_number + "_name";
alert(document.getElementById("'" + ben_name.toString() + "'").value);
}
}
}
here bene_account_number_edit are the radio buttons.
Thanks
Are you storing just an integer as the element's id attribute? If so, browsers tend to behave in strange ways when looking for an element by an integer id. Try passing account_number.toString(), instead.
If that doesn't work, prepend something like "account_" to the beginning of your elements' id attributes and then call document.getElementById('account_' + account_number).value.
Why are you prefixing and post-fixing ' characters to the name string? ben_name is already a string because you've appended '_name' to the value.
I'd recommend doing a console.log of ben_name just to be sure you're getting the value you expect.
the way to use a variable for document.getElementById is the same as for any other function:
document.getElementById(ben_name);
I don't know why you think it would act any differently.
There is no use of converting ben_name to string because it is already the string.
Concatenation of two string will always give you string.
var account_number = acc_list[i].value.toString();
var ben_name = account_number + "_name";
try following code it will work fine
var ben_name=acc_list[i]+ "_name";
here also
alert(document.getElementById("'" + ben_name.toString() + "'").value);
try
alert(document.getElementById(ben_name).value);
I have tested similar type of code which worked correctly. If you are passing variable don't use quotes. What you are doing is passing ben_name.toString() as the value, it will definitely cause an error because it can not find any element with that id viz.(ben_name.toString()). In each function call, you are passing same value i.e. ben_name.toString() which is of course wrong.
I found this page in search for a fix for my issue...
Let's say you have a list of products:
<div class="rel-prod-item">
<img src="assets/product-photos/title-of-the-related-product_thumbnail.jpg" alt="Western Digital 1TB" />
<p class="rel-prod-title">Western Digital 1TB</p>
<p class="rel-prod-price" id="price_format_1">149.95</p>
add to cart
</div>
<div class="rel-prod-item">
<img src="assets/product-photos/title-of-the-related-product_thumbnail.jpg" alt="Western Digital 1TB" />
<p class="rel-prod-title">Western Digital 1TB</p>
<p class="rel-prod-price" id="price_format_2">139.95</p>
add to cart
</div>
<div class="rel-prod-item">
<img src="assets/product-photos/title-of-the-related-product_thumbnail.jpg" alt="Western Digital 1TB" />
<p class="rel-prod-title">Western Digital 1TB</p>
<p class="rel-prod-price" id="price_format_3">49.95</p>
add to cart
</div>
The designer made all the prices have the digits after the . be superscript. So your choice is to either have the cms spit out the price in 2 parts from the backend and put it back together with <sup> tags around it, or just leave it alone and change it via the DOM. That's what I opted for and here's what I came up with:
window.onload = function() {
var pricelist = document.getElementsByClassName("rel-prod-price");
var price_id = "";
for (var b = 1; b <= pricelist.length; b++) {
var price_id = "price_format_" + b;
var price_original = document.getElementById(price_id).innerHTML;
var price_parts = price_original.split(".");
var formatted_price = price_parts[0] + ".<b>" + price_parts[1] + "</b>";
document.getElementById(price_id).innerHTML = formatted_price;
}
}
And here's the CSS I used:
.rel-prod-item p.rel-prod-price b {
font-size: 50%;
position: relative;
top: -4px;
}
I hope this helps someone keep all their hair :-)
Here's a screenshot of the finished product

Categories