I am trying to create my own javascript simple template function
I want to create a html page that will look like this
<p>
{{HELLO_WORLD}}
<br />
{{MY_NAME_IS}}
</p>
and than with javascript to replace anything that is in {{}}
with a json var that will look like this
{HELLO_WORLD: "Hello World!", MY_NAME_IS: "My name is"}
I am a little confused about the right method to do this.
the point is to make a multilanguage web site, that way I load the json for the desired language.
thank's.
JavaScript supports regular expression-based find-and-replace, with functions for the replacement. So you can do this:
myInputString.replace( /\{\{([^\}]*)\}\}/g, function( s, v ) { return myJSON[v] } );
To explain:
replace takes 2 arguments. The first is a regular expression object. In this case we build one inline using JavaScript's /expression/flags syntax. It looks for 2 opening braces (which need to be escaped because they have special meaning in regular expressions) followed by any characters which are not a closing brace, followed by 2 closing braces. The g means "global", so that it will match all cases rather than just the first one.
When a match is found, the function will be called. The first argument (I called it s) is the full matched string (like "{{abc}}"), the second (I called it v) is set to the first bit in brackets (like "abc").
In real code, you should add error checking (variables which don't exist), and possibly convert to lowercase / whatever.
Full details on replace are here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
Related
Recently I found some interesting codes on a website.
<div class="inputArea">
<textarea type="text" id="textInput" class="chatInput lightBorder"></textarea>
</div>
<b>Send</b>
When I click the "Send" button (it's a hyperlink, but it looks like a button on the page") and it will fire the js code "sendMsg#.inputArea". What it does is to send a message in the textarea to the server. It acts like the sendMsg is a function and .inputArea is a parameter passed to that function. But it does not seem to follow the EMAC standard. However, it works. How is it possible? It now looks like black magic to me. Can someone explain how the # character works in the code?
Updated Answer
...now that you've shown what you think is "JavaScript code."
This isn't JavaScript code:
<b>Send</b>
<!-- Not JavaScript Code ----------------------^^^^^^^^^^^^^^^^^^ -->
That's just an attribute value on an element. (And an invalid one, a doesn't have a click attribute.) Presumably code in their JavaScript understands what to do with it. You're confusing that with an onclick attribute, which would (normally) contain JavaScript code.
Original Answer
You can't use # in a property name literal, variable name, or function name (collectively, an IdentifierName) in JavaScript.*
how to declare a special character in js
You can't. The characters allowed in IdentifierName are defined by the specification and are not extensible.
You can use any character you like as a property name (but not variable or function name), but not as a literal, only if you use brackets notation and a string, e.g.:
var obj = {"SendMsg#": "foo"};
console.log(obj["SendMsg#"]); // "foo"
* That said, JavaScript is very liberal about the characters you can use in IdentiferName, so while # isn't allowed, I couldn't absolutely guarantee there isn't some other Unicode character that looks a bit like it that's allowed. But I suspect not, as the Unicode page for # doesn't list any characters likely to be confused with #.
# isn't special at all in JavaScript, other than the fact that it isn't valid in identifiers - as in you can't use it for function and variable names. You can't declare custom operators in javascript, so unless you get to speak to the one who built that site, there's no way to tell what they do with # in strings.
On another note, many special characters are valid in JS, so you can name a function $, _ or even q̊̆̓̍u̐͂e̷̜r̤̻̫ͅy̎ if you want. But # isn't one of them.
I'm working on a very basic templating system and struggling.
Take this:
some useless text here but i want to replace %% this %% with the variable: object.this
This seems like it'd be easy, but I can't figure it out. Here's my code:
function loadTemplate(element, object) {
var regex = /%% (.*) %%/;
return $(element).html().replace(regex, eval("object.$1"));
}
I've tried a few different things. Currently the eval returns undefined. When I try eval("$1"), it gives me an uncaught reference error and tells me that $1 isn't defined.
You don't need eval as replace takes a callback function; do your logic there. The first parameter is the matched substring, the second one is the first capturing group match. Using bracket notation you can access the object's key dynamically with a string:
.replace(regex, function(_, a) {
return object[a];
});
I am writing a micro-templating script where parts of a string are replaced with object options. Here is a short example:
var person = {name:"Smith",age:43};
var string = "I am {name} and I am {age} years old";
document.write(string.replace(/{([\s\S]+?)}/g,(person['$1']||"")));
document.write("<br/>");
document.write(string.replace(/{([\s\S]+?)}/g
, function($0,$1){return person[$1]||"";}));
Also in a JS Fiddle
The second expression works fine, but not the first one. Could anybody explain why? I thought $1 could be directly used as a back reference within a string.
$1, $2, ..., $& can only be used when they're part of a string value passed to replace:
string.replace(/{([\s\S]+?)}/g, '$1(matched)');
// result: "I am name(matched) and I am age(matched) years old"
But, the 1st snippet is effectively:
document.write(string.replace(/{([\s\S]+?)}/g,""));
That's because (person['$1']||"") is not a value that can be passed as-is. It's a property-lookup and logical-or that will be evaluated first and their resulting value -- "" -- will be what's actually passed to replace.
To be able to evaluate an expression after you have a match, you have to use a function to delay the evaluation, as you have in the 2nd snippet.
It makes sense to me, I mean if you look at this:
person['$1']
You're basically saying "give me the object $1 inside person" which in this case is undefined. I guess it tries to evaluate the object before the regex capture group. That's why you have the function replacement and it works, for this circumstances.
RegExp.replace method attempts to parse $n expressions (as well as $& and several others - look here for complete list) only within strings. But something like person['$1'] is not a string - it's an expression which may be (or may be not) evaluated to string. Only after this evaluation the backreference 'markers' will be parsed.
I suppose the callback in replace is the only quite normal way to go in your case.
You don't have single quotes around the $1 in the second regex.
ok i do have this following data in my div
<div id="mydiv">
<!--
what is your present
<code>alert("this is my present");</code>
where?
<code>alert("here at my left hand");</code>
oh thank you! i love you!! hehe
<code>alert("welcome my honey ^^");</code>
-->
</div>
well what i need to do there is to get the all the scripts inside the <code> blocks and the html codes text nodes without removing the html comments inside. well its a homework given by my professor and i can't modify that div block..
I need to use regular expressions for this and this is what i did
var block = $.trim($("div#mydiv").html()).replace("<!--","").replace("-->","");
var htmlRegex = new RegExp(""); //I don't know what to do here
var codeRegex = new RegExp("^<code(*n)</code>$","igm");
var code = codeRegex.exec(block);
var html = "";
it really doesn't work... please don't give the exact answer.. please teach me.. thank you
I need to have the following blocks for the variable code
alert("this is my present");
alert("here at my left hand");
alert("welcome my honey ^^");
and this is the blocks i need for variable html
what is your present
where?
oh thank you! i love you!! hehe
my question is what is the regex pattern to get the results above?
Parsing HTML with a regular expression is not something you should do.
I'm sure your professor thinks he/she was really clever and that there's no way to access the DOM API and can wave a banner around and justify some minor corner-case for using regex to parse the DOM and that sometimes it's okay.
Well, no, it isn't. If you have complex code in there, what happens? Your regex breaks, and perhaps becomes a security exploit if this is ever in production.
So, here:
http://jsfiddle.net/zfp6D/
Walk the dom, get the nodeType 8 (comment) text value out of the node.
Invoke the HTML parser (that thing that browsers use to parse HTML, rather than regex, why you wouldn't use the HTML parser to parse HTML is totally beyond me, it's like saying "Yeah, I could nail in this nail with a hammer, but I think I'm going to just stomp on the nail with my foot until it goes in").
Find all the CODE elements in the newly parsed HTML.
Log them to console, or whatever you want to do with them.
First of all, you should be aware that because HTML is not a regular language, you cannot do generic parsing using regular expressions that will work for all valid inputs (generic nesting in particular cannot be expressed with regular expressions). Many parsers do use regular expressions to match individual tokens, but other algorithms need to be built around them
However, for a fixed input such as this, it's just a case of working through the structure you have (though it's still often easier to use different parsing methods than just regular expressions).
First lets get all the code:
var code = '', match = [];
var regex = new RegExp("<code>(.*?)</code>", "g");
while (match = regex.exec(content)) {
code += match[1] + "\n";
}
I assume content contains the content of the div that you've already extracted. Here the "g" flag says this is for "global" matching, so we can reuse the regex to find every match. The brackets indicate a capturing group, . means any character, * means repeated 0 or more times, and ? means "non-greedy" (see what happens without it to see what it does).
Now we can do a similar thing to get all the other bits, but this time the regex is slightly more complicated:
new RegExp("(<!--|</code>)(.*?)(-->|<code>)", "g")
Here | means "or". So this matches all the bits that start with either "start comment" or "end code" and end with "end comment" or "start code". Note also that we now have 3 sets of brackets, so the part we want to extract is match[2] (the second set).
You're doing a lot of unnecessary stuff. .html() gives you the inner contents as a string. You should be able to use regEx to grab exactly what you need from there. Also, try to stick with regEx literals (e.g. /^regexstring$/). You have to escape escape characters using new RegExp which gets really messy. You generally only want to use new RegExp when you need to put a string var into a regEx.
The match function of strings accepts regEx and returns a collection of every match when you add the global flag (e.g. /^regexstring$/g <-- note the 'g'). I would do something like this:
var block = $('#mydiv').html(), //you can set multiple vars in one statement w/commas
matches = block.match(/<code>[^<]*<\/code>/g);
//[^<]* <-- 0 or more characters that aren't '<' - google 'negative character class'
matches.join('_') //lazy way of avoiding a loop - join into a string with a safe character
.replace(/<\/*code>/g,'') //\/* 0 or more forward slashes
.split('_');//return the matches string back to array
//Now do what you want with matches. Eval (ew) or append in a script tag (ew).
//You have no control over the 'ew'. I just prefer data to scripts in strings
I am generating XML using Javascript. It works fine if there are no special characters in the XML. Otherwise, it will generate this message: "invalid xml".
I tried to replace some special characters, like:
xmlData=xmlData.replaceAll(">",">");
xmlData=xmlData.replaceAll("&","&");
//but it doesn't work.
For example:
<category label='ARR Builders & Developers'>
Thanks.
Consider generating the XML using DOM methods. For example:
var c = document.createElement("category");
c.setAttribute("label", "ARR Builders & Developers");
var s = new XMLSerializer().serializeToString(c);
s; // => "<category label=\"ARR Builder & Developers\"></category>"
This strategy should avoid the XML entity escaping problems you mention but might have some cross-browser issues.
This will do the replacement in JavaScript:
xml = xml.replace(/</g, "<");
xml = xml.replace(/>/g, ">");
This uses regular expression literals to replace all less than and greater than symbols with their escaped equivalent.
JavaScript comes with a powerful replace() method for string objects.
In general - and basic - terms, it works this way:
var myString = yourString.replace([regular expression or simple string], [replacement string]);
The first argument to .replace() method is the portion of the original string that you wish to replace. It can be represented by either a plain string object (even literal) or a regular expression.
The regular expression is obviously the most powerful way to select a substring.
The second argument is the string object (even literal) that you want to provide as a replacement.
In your case, the replacement operation should look as follows:
xmlData=xmlData.replace(/&/g,"&");
xmlData=xmlData.replace(/>/g,">");
//this time it should work.
Notice the first replacement operation is the ampersand, as if you should try to replace it later you would screw up pre-existing well-quoted entities for sure, just as ">".
In addition, pay attention to the regex 'g' flag, as with it the replacement will take place all throughout your text, not only on the first match.
I used regular expressions, but for simple replacements like these also plain strings would be a perfect fit.
You can find a complete reference for String.replace() here.