Fetch HTML element value from json stingrigy value using Javascript - javascript

I have object which i have converted using JSON.stingrify
{
"_originalElementInner": " <input type=\"file\" name=\"\" class=\"hidden\" id=\"file_input_two\" onchange=\"alertFilename(this.value,'cropped_two');\"> <!-- <img src=\"https://dxyz.com/tmp/5bd432ed2d8dd_img3.jpg\" alt=\"\" width=\"100%\" height=\"100%\"> --> "
}
From above i want to fetch "cropped_two", which is on
onchange=\"alertFilename(this.value,'cropped_two');
Here this.value will remain same, so if in case want to split the string .
I have tried via multiple ways by looping and other but in vain.
Anyone can help ?
Thanks in advance.

I think you just want the string? I guess this would work.
let o = {
"_originalElementInner": " <input type=\"file\" name=\"\" class=\"hidden\" id=\"file_input_two\" onchange=\"alertFilename(this.value,'cropped_two');\"> <!-- <img src=\"https://dxyz.com/tmp/5bd432ed2d8dd_img3.jpg\" alt=\"\" width=\"100%\" height=\"100%\"> --> "
};
const regex = /,(.*)\);/gm;
const match = regex.exec(o._originalElementInner);
console.log(match[1]);

you can use a search function to find "this.value" position, then use substring function from "this.value" position + 11 to the position of ")" witch seems to be the only ")" in the string.

If it is possible to use jQuery, you can follow this approach.
var obj = {"_originalElementInner": " <input type=\"file\" name=\"\" class=\"hidden\" id=\"file_input_two\" onchange=\"alertFilename(this.value,'cropped_two');\"> <!-- <img src=\"https://dxyz.com/tmp/5bd432ed2d8dd_img3.jpg\" alt=\"\" width=\"100%\" height=\"100%\"> --> "},
stringValue = '',
// This function will be called when the event change is triggered.
alertFilename = function(_, str) { stringValue = str;};
// Create the jQuery object and trigger the event change
// Finally remove the function from window object (This is just to remove an unsed function after execute it).
$(obj['_originalElementInner']).trigger('change'), (delete window['alertFilename']);
console.log(stringValue);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

If there could be several onchange callbacks in your code, the following code will get the one that refers to alertFilename, it is also faster than regexp.
function extractSecondArg(text) {
// Define the pattern to look for.
const pattern = 'onchange=\"alertFilename(this.value,'
// Find the index of the pattern.
const patternIndex = text.indexOf(pattern);
if (patternIndex !== -1) {
// Find the closing parenthesis.
const patternEnd = ');';
const patternEndIndex = text.indexOf(patternEnd, patternIndex);
// Extract the second argument of the function.
return text.substring(patternIndex + pattern.length, patternEndIndex).replace(/["']+/g, '');
}
}
Here is an example of how to use it.
const json = {
"_originalElementInner": " <input type=\"file\" name=\"\" class=\"hidden\" id=\"file_input_two\" onchange=\"alertFilename(this.value,'cropped_two');\"> <!-- <img src=\"https://dxyz.com/tmp/5bd432ed2d8dd_img3.jpg\" alt=\"\" width=\"100%\" height=\"100%\"> --> "
};
// Extract element to search in.
const secondArg = extractSecondArg(json['_originalElementInner']);
console.log(secondArg)

Related

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>

Creating a new div for each element for two different arrays using JQuery

I want to create a dialog box with images and text. I have an array of images and names. I want to create a new div for each image and name. Not sure if I'm iterating the items correctly and if and why this doesn't work. Right now, I'm getting a syntax error and the 'i' is undefined when I run this code. Any guidance would be appreciated.
var itemImages = ["image1", "image2", "image3"]
var itemNames = ["name1", "name2", "name3"]
var message = '<div class="box-cart-products">
<script>$(itemImages).each(function(i, e){$(".box-cart-
products").append("<div class="box-cart-product"><div class="box-cart-
product-image"><img src="'+itemImages[i]+'"/></div><div
class="box-cart-product-name"><span>'+itemNames[i]+'</span></div>
</div>")})</script></div>'
$(message).dialog()
Here's the breakdown of my message variable.
<div class="box-cart-products">
<script>
$(itemImages).each(function(i, e){
$(".box-cart-products").append(
"<div class="box-cart-product">
<div class="box-cart-product-image"><img src="'+itemImages[i]+'"/></div>
<div class="box-cart-product-name"><span>'+itemNames[i]+'</span></div>
</div>"
)
})
</script>
</div>
I think the issue just had to do with ' vs ". Make sure when you have to mix and match them, use one to start/stop your string and the other inside the string (or you can escape the characters but I find that more difficult to read).
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box-cart-products"></div>
<script>
var itemImages = ["image1", "image2", "image3"]
var itemNames = ["name1", "name2", "name3"]
$(itemImages).each(function(i, e) {
$(".box-cart-products").append(
'<div class="box-cart-product"> <div class="box-cart-product-image"><img src="' + itemImages[i] + '"/> </div> <div class="box-cart-product-name"> <span>' + itemNames[i] + '</span></div></div>'
)
})
</script>

How to get text of div by id in variable

I have a string variable called the res.
Within this variable there is HTML code.
Each Div in variable within the has a id.
var res = "<div id="1">1</div>
<div id="2">12</div>
<div id="3">123</div>
<div id="4">1234</div>";
var content-div-1 = ??;
var content-div-2 = ??;
var content-div-3 = ??;
var content-div-4 = ??;
I would like to give the id of div and give me values of inside Div.
The question has been answered, but there's an alternative without jQuery
var res = '<div id="1">1</div>'+
'<div id="2">12</div>'+
'<div id="3">123</div>'+
'<div id="4">1234</div>';
function findMe(txt, id){
var matches = txt.match(new RegExp('<div\\s+id="'+id+'">[\\S\\s]*?<\\/div>'), 'gi');
if(matches) return matches[0].replace(/(<\/?[^>]+>)/gi, '');
return '';
}
var content1 = findMe(res,1);
var content2 = findMe(res,2);
var content3 = findMe(res,3);
var content4 = findMe(res,4);
JSFiddle
As you've tagged your question jquery, I assume this is in a browser context (or some other context with a DOM). If so, the simplest way to is to parse the HTML and use the resulting disconnected DOM tree:
var res = '<div id="1">1</div>' +
'<div id="2">12</div>' +
'<div id="3">123</div>' +
'<div id="4">1234</div>';
var parsed = $(res);
var contentDiv1 = parsed.filter("[id=1]").text(); // See note below
snippet.log("1: " + contentDiv1);
var contentDiv2 = parsed.filter("[id=2]").text(); // See note below
snippet.log("2: " + contentDiv2);
// ...and so on (or use a loop)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Note: Although id value starting with digits are valid HTML, it's awkward to use them because in a CSS id selector (#foo), you can't start the ID value with an unescaped digit (e.g., #1 is an invalid selector). That's why I've had to use the attribute selector [id=1] above. You can work around it with escaping, but by far the best option is just to not start ID values with digits in the first place.

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=\"" + .......

passing string values with special characters to a function 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.

Categories