Trouble With Regex and Velocity - regex

I just started using dotCMS for work to modify the existing website. I am trying to create a widget that takes a custom structure field called urlTitle. It takes the Title of an event and makes it url friendly. Here is a tutorial describing the urlTitle
I have a regex that is written fine for javascript. My problem is when I try to use the same regex in velocity, I am getting some troubles.
Here is the javascript from the tutorial:
<script>
function updateDisplayURLTitle(){
// get the title entered by the user
var plainTitle = dojo.byId("title");
// make a friendly url
var urlTitle = plainTitle.value.toLowerCase();
urlTitle= urlTitle.replace(/^\s+|\s+$/g,"");
urlTitle = urlTitle.replace(/[^a-zA-Z 0-9]+/g,' ');
urlTitle = urlTitle.replace(/\s/g, "-");
while(urlTitle.indexOf("--") > -1){
urlTitle = urlTitle.replace("--",'-');
}
// set the values of the display place holder and the custom field
// the is to hold the div open
dojo.byId("displayURLTitle").innerHTML = urlTitle;
dojo.byId("urlTitle").value=urlTitle;
}
// attach this the text1 field onchange
dojo.connect(dojo.byId("title"), "onchange", null, "updateDisplayURLTitle");
// populate the field on load
dojo.addOnLoad(updateDisplayURLTitle);
</script>
<div id="displayURLTitle" style="height:20px"> </div>
Then here is my velocity code for my widget:
#set($nowsers = $date.format('yyyyMMddHHmmss', $date.getDate()))
#set($con = $dotcontent.pull("+structureName:calendarEvent +(conhost:48190c8c-42c4-46af-8d1a-0cd5db894797 conhost:SYSTEM_HOST) +calendarEvent.startDate:[$nowsers TO 21001010101000]",1,"calendarEvent.startDate"))
<ul>
#foreach($event in $con)
<li>
$event.title
<p> $event.description</p>
</li>
#set($temp = $event.title.toLowerCase())
#set($temp = $temp.replaceAll('/^\s+|\s+$/g', ""))
#set($temp = $temp.replaceAll('/[^a-zA-Z 0-9]+/g', " "))
#set($temp = $temp.replaceAll('/\s/g', "-"))
$temp
$temp
#end
My goal is to have the regex from the javascript work with the velocity. Right now it doesn't work and I'm not that skilled with regex, so far my research has lead me nowhere.
Another thing I cant figure out is what the /g does. I can't find it in any regex resource website.

I figured it out. It turns out that the escape characer / in front of the regex patter, and the /g were causing the pattern to fail so it must not be needed for the method used in velocity.

Related

Hide Tooltip for HTML5 validation defined in ASP.NET/MVC

When the input does not match the pattern specified by the pattern attribute, the browser displays "You must use this format:" in a tooltip on the field.
I cannot hide this tooltip message at all, can I? 'Cause even when I write
#Html.TextBoxFor(model => model.tbMyNumber, new { #pattern = "[0-9]{6,}", title="" })
it stills brings "You must use this format:" in the tooltip for this field.
How can I avoid this?
I don't think there is a way to do what you want without adding javascript. A simple alternative would be to verify with javascript (example below shown using jQuery) instead...
$('#myform').submit(function() {
if(!/^[0-9]{6,}$/.test($('#mytext').val())) {
return false;
}
});
This would prevent the form from submitting if the value doesn't match the pattern... without displaying the tooltip... just make sure you have an alternative so the user doesn't wonder why they can't submit the form.
I guess that is not what you expect as answer, but you can probably work the problem around with javascript
HTML:
* The string must be at least 6 digits
<br/>
<input type="text" onkeyup="isNumber(this)" onblur="lengthValidation(this)">
Javascript:
function isNumber(textbox)
{
textbox.value = textbox.value.replace(/[\D]+/, '');
}
function lengthValidation(textbox)
{
if (textbox.value.length < 6) {
document.getElementById("error").style.display = 'block';
} else {
document.getElementById("error").style.display = 'none';
}
}
Test it here: https://jsfiddle.net/mvxeous4/1/

Hyperlinks inside object fields

I have an object inside my Ember app, with a description field. This description field may contain hyperlinks, like this
My fancy text <a href='http://other.site.com' target='_blank'>My link</a> My fancy text continues...
However, when i output it normally, like {{ description }} my hyperlinks are displayed as a plain text. Why is this happening and how can i fix this?
Handlebars escapes any HTML within output by default. For unescaped text in markup use triple-stashes:
{{{ description }}}
There's an alternative when one controls the property: Handlebars.SafeString. SafeStrings are assumed to be safe and are not escaped either. From the documentation:
Handlebars.registerHelper('link', function(text, url) {
text = Handlebars.Utils.escapeExpression(text);
url = Handlebars.Utils.escapeExpression(url);
var result = '' + text + '';
return new Handlebars.SafeString(result);
});
Note - please be careful with this. There are security concerns with rendering unescaped text that has come from user input; an attacker could inject a malicious script into the description and hijack your page, for example.

Coldfusion Regex to convert a URL to lowercase

I am trying to take convert urls in a block of html to ensure they are lowercase.
Some of the links are a mix of uppercase and lowercase and they need to be converted to just lowercase.
It would be impossible to run round the site and redo every link so was looking to use a Regex when outputting the text.
<p>Hello world Some link.</p>
Needs to be converted to:
<p>Hello world Some link.</p>
Using a ColdFusion Regex such as below (although this doesn't work):
<cfset content = Rereplace(content,'(http[*])','\L\1','All')>
Any help much appreciated.
I think I would use the lower case function, lCase().
Put your URL into a variable, if it's not already:
<cfset MyVar = "http://www.ThisSite.com">
Force it to lower case here:
<cfset MyVar = lCase(MyVar)>
Or here:
<cfoutput>
Some Link
</cfoutput>
UPDATE: Actually, I see that what you are actually asking is how to generate your entire HTML page (or a big portion) and then go back through it, find all of the links, and then lower their cases. Is that what you are trying to do?
Since you have the HTML stored in a database, there is a bit more work that needs to be done than just using lcase(). I would wrap the functionality into a function that can be easily reused. Check out this code for an example.
content = '<p>Hello world Some link.</p>
<p>Hello world Some link.</p>
<p>Hello world <a href=''http://www.somelink.com/BLARG''>Some link</a>.</p>';
writeDump( content );
writeDump( fixLinks( content ) );
function fixLinks( str ){
var links = REMatch( 'http[^"'']*', str );
for( var link in links ){
str = replace( str, link, lcase( link ), "ALL" );
}
return str;
}
This has only been tested in CF9 & CF10.
Using REMatch() you get an array of matches. You then simply loop over that array and use replace() with lcase() to make the links lowercase.
And...based on Leigh's suggestion, here is a solution in one line of code using REReplace()
REReplace( content, '(http[^"'']*)', '\L\1', 'all' )
Use a HTML parser to parse HTML, not regex.
Here's how you can do it with jQuery:
<!doctype html>
<script src="jquery.js"></script>
<cfsavecontent variable="HtmlCode">
<p>Hello world Some link.</p>
</cfsavecontent>
<pre></pre>
<script>
var HtmlCode = "<cfoutput>#JsStringFormat(HtmlCode)#</cfoutput>";
HtmlCode = jQuery('a[href]',HtmlCode).each( lowercaseHref ).end().html();
function lowercaseHref(index,item)
{
var $item = jQuery(item);
// prevent non-links from being changed
// (alternatively, can check for specific domain, etc)
if ( $item.attr('href').startsWith('#') )
return
$item.attr( 'href' , $item.attr('href').toLowerCase() );
}
jQuery('pre').text(HtmlCode);
</script>
This works for href attributes on a tags, but can of course be updated for other things.
It will ignore in-page links like <a href="#SomeId"> but not stuff like <a href="/HOME/#SomeId"> - if that's an issue you'd need to update the function to exclude page fragment part (e.g. split on # then rejoin, or whatever). Same goes if you might have case-sensitive querystrings.
And of course the above is just jQuery because I felt like it - you could also use a server-side HTML parser, like jSoup to achieve this.

JavaScript client side (user input) find-and-replace Hyperlinks

I want a clientside user to be able to insert text in text input box, click 'replace' and have a list of hyperlinks replaced accordingly. Anchor text will stay the same, but the hyperlink will change.
My problem: I am only getting the first hyperlink to change. I have a fiddle set up with two links, and you can see only the first changes. I want a list of, say, 20 links to change at once.
jsfiddle.net/TKxuf/
HTML:
<input id="replace" type="text" value="newphrase" />
<input onclick="doReplace()" type="button" value="Replace!" />
<br/>
<p id="list">Google Keyword Search</p>
<p id="list">Yahoo Keyword Search</p>
JavaScript:
function doReplace() {
var s = "keyword";
var r = document.getElementById('replace').value;
var oldtext = document.getElementById('list').innerHTML;
var newtext = oldtext.replace( s, r );
console.log(s);
console.log(r);
console.log(document.getElementById('list'));
document.getElementById('list').innerHTML = newtext;
}
I can't work out why you'd want the original strings in the HTML page code to begin with, so I'd suggest that you may have a problem with your approach. Note also that it's illegal in HTML to have more than one element with the same Id, which mostly explains why getElementById only returns one item. Also external urls must be preceded by http:// too.
I usually use jQuery these days - in jQuery you could simply swap id="list" to class="list" and use $('.list') to get a list of them all. $('.list').each(function() { var item = this; /* manipulation code here */ }); would allow you to change them all, but you may have to do some reading.
In any case, I still think that your approach is wrong.
What I'd do is have a normal javascript array of Urls, with replacable keys that are difficult to confuse as part of the url, e.g.
var addresses = [
{ text: "Google Keyword Search", url: "http://google.com?q=%keyword%" },
{ text: "Yahoo Keyword Search", url: "http://yahoo.com?q=%keyword%" }
];
When your user searches, you then build up your new html code into a string by iterating through the array:
var output = '';
for (var i = 0; i<addresses.length; i++) {
var item = addresses[i];
output += '<p>'+item.text+'</p>';
}
Note: I haven't checked this code, but you should be able to get the idea. You'd actually write out all the entire list by using innerHTML on the list container.
Hope that this helps.
Best Regards,
Mark Rabjohn
Integrated Arts Limited

How To I Replace New Elements Added To A Page With Jquery

Here is the scenario... I have a a checkbox next to each field that I am replacing on page load with jquery with "Delete" text that enables me to delete the field via jquery, which is working fine. Like so...
$(".profile-status-box").each(function(){ $(this).replaceWith('<span class="delete">' + 'Delete' + '</span>') });
The problem comes in however is that after page load, I am also giving the user the option to dynamically add new fields. The new added fields though have the checkbox and not the delete link because they are not being replaced by jquery since they are being added after the initial page load.
Is't possible to replace the content of new elements added to the page without doing a page refresh? If not, I can always have two templates with different markup depending one for js and one for non js, but I was trying to avoind taht.
Thanks in advance.
You can use the .livequery() plugin, like this:
$(".profile-status-box").livequery(function(){
$(this).replaceWith('<span class="delete">Delete</span>')
});
The anonymous function is run against every element found, and each new element matching the selector as they're added.
Have a look at this kool demo. It removes and adds elements like a charm.
http://www.dustindiaz.com/basement/addRemoveChild.html
Here's how:
First of all, the (x)html is real simple.
xHTML Snippet
<input type="hidden" value="0" id="theValue" />
<p>Add Some Elements</p>
<div id="myDiv"> </div>
The hidden input element simply gives you a chance to dynamically call a number you could start with. This, for instance could be set with PHP or ASP. The onclick event handler is used to call the function. Lastly, the div element is set and ready to receive some children appended unto itself (gosh that sounds wierd).
Mkay, so far so easy. Now the JS functions.
addElement JavaScript Function
function addElement() {
var ni = document.getElementById('myDiv');
var numi = document.getElementById('theValue');
var num = (document.getElementById('theValue').value -1)+ 2;
numi.value = num;
var newdiv = document.createElement('div');
var divIdName = 'my'+num+'Div';
newdiv.setAttribute('id',divIdName);
newdiv.innerHTML = 'Element Number '+num+' has been added! <a href=\'#\' onclick=\'removeElement('+divIdName+')\'>Remove the div "'+divIdName+'"</a>';
ni.appendChild(newdiv);
}
And if you want to,
removeElement JavaScript Function
function removeElement(divNum) {
var d = document.getElementById('myDiv');
var olddiv = document.getElementById(divNum);
d.removeChild(olddiv);
}
and thats that. bobs your uncle.
This is taken from this article/tutorial: http://www.dustindiaz.com/add-and-remove-html-elements-dynamically-with-javascript/
I've just learnt this myself. thank you for the question
Hope that helps.
PK