My code in JSP file looks like this :
<s:form namespace="/user" action="list" method="POST" id="filterListForm" theme="simple"
onsubmit="document.getElementById('filterSearchText').value=document.getElementById('filterSearchText').value.replace(/\\/g,'')">
It won't replace the backslash char. I've tried the following, none of them work :
replace('/\\/g','')
replace(/\\\\/g,'')
replace(\/\\\/g,'')
But if I change it to the following, it works :
<s:form namespace="/user" action="list" method="POST" id="filterListForm" theme="simple"
onsubmit="replaceBackslash()">
<script type="text/javascript">
function replaceBackslash() { document.getElementById('filterSearchText').value=document.getElementById('filterSearchText').value.replace(/\\/g,''); }
</script>
Why ? Is there a way to make it work in the first case ?
You want:
var replaced = original.replace(/\\/g, '');
In a regular expression literal, all you need to do is double the backslash to quote it.
As to why it doesn't work when you try passing the code in via a JSP tag, well that would probably be JSP mangling the string for you. It might work to do this:
<s:form ... onsubmit=' ... .replace(/\\\\/g, "") ... ' >
but I don't have a good way to try that at the moment.
edit — actually I'm finding this challenging. It probably depends on what your tag library does. My framework (Stripes) likes to HTML-escape attribute values, so it's hard to pass through something like \ (well, impossible).
(This isn't really a solution, just a recommendation of a general practice that happens to solve this problem, too.)
Bottom line: Go with separated Javascript. If you feel it's too much work to completely separate it out into a different file (even though that would help you cleanly avoid all issues such as this), at least put it all in a script tag at the bottom. It helps separate layout and logic, and it keeps all the Javascript in one known place, making it easier to understand and maintain. You don't even need onclick/onsubmit attributes, you can assign those in Javascript too (usually keyed on html #id attributes). If you use the on[event] attributes anyway, just call one sensibly named function, and put the function's implementation in your main script.
Related
I am using Javascript to define a button behaviour on a web page. The behaviour I am after is to insert some new HTML somewhere on my page, but I would like to use the MVC extension method Html.EditorFor to define the new HTML which will be inserted.
What I would like to do is the following:
$("#myButton").click(function() {
$("#(Html.EditorFor(x => x.SomeModelProperty))").insertBefore(<somewhere>);
});
The problem I'm encountering is that the MvcHtmlString returned by the call to EditorFor renders as multi-line HTML, resulting in invalid Javascript:
$("<div>
<label for="ModelData_SomeModelProperty">SomeModelProperty</label>
</div>
<div> ....
In an ideal world, I could get EditorFor to somehow render all of the above on a single line, or use some kind of special Javascript syntax to define a multi-line string (like using single quotes in C#), but so far I'm drawing a blank.
I've tried calling ToHtmlString and hand-editing the resulting string to remove line-breaks, and I'm aware that I can escape the new lines in Javascript using a /, but the problem with doing so is that I then have to handle the escaped HTML, which looks a little like the following:
$("<div>
<label for="ModelData_SomeModelProperty">SomeModelProperty</label>
</div>
<div> .... (you get the idea)
I was just wondering whether anyone had tried anything similar and might have a more elegant approach?
One way would be to get it written into a hidden div in html instead of directly into the javascript. Then you can just read it from the dom to use in you script.
So you page would have a
<div style="display:none" id="hiddenArea">
...insert whatever you want in here
with newline or whatever...
</div>
And then in your javascript:
$("#myButton").click(function() {
var source = $("#hiddenArea").html();
$(source).insertBefore(<somewhere>);
});
You could maybe create a HTML helper so you much more control on what's returned and how it is formatted.
http://www.codeproject.com/Tips/720515/Custom-HTML-Helper-for-MVC-Application
I have a form that I am validating with JS on the front-end and PHP on the server side. What I need is a way to reliably count the number of links in an HTML string. The best way that I could think of was to count the closing tags. However simply searching for this tag will not work because the user could circumvent the validation by adding spaces like so: </a >.
I am fairly new to regex and this is the pattern that I have been able to come up with so far:
<[ \n\t]*\/[ \n\t]*a[ \n\t]*>
In Javascript:
function link_count(s){
return s.match(/<[ \n\t]*\/[ \n\t]*a[ \n\t]*>/g, s).length;
}
In PHP:
function count_links($str){
return preg_match_all('<[ \n\t]*/[ \n\t]*a[ \n\t]*>', $str, $matches);
}
Is this the best approach? Will it affect the performance of my form (the html string could be very long)? I am looking for the most efficient and reliable solution.
Thanks in advance.
So, like #sgroves said, </a> are not all links. checking for href might be more interesting.
Also, why not checking the opening tag directly?
I tried searching for <a .... href>
You might use the 's' modifier to ignore newlines...
/<\s*\ba\b.*?href/gs
http://regex101.com/r/bG8lN1/3
In an HTML file I have the following:
<input type="..." name="myInput1" />
In a corresponding JS file I have the following variable which will hold the string value of that input after blur:
var myInput1;
Is there any problem in having these two identical names? I'm guessing that the namespaces are separate so it is ok.
Short answer, no problem whatsoever.
A short answer is, indeed, no. However, it also greatly depends on how you use the variable. Let's consider that you use javascript for validating that the variable is set as follows:
if(myInput1) {do something}
If you also decide to set the id to be the same as the name is as follows (cause you didn't specify that, it can be anything):
<input type="myInput1" name="myInput1" />
your variable myInput1 will be set to contain the DOM element and won't be empty anymore.
This link between JS and HTML is not only interesting but can be used to create an exploit as described in the section 3.1.2 of Postcards from the post-XSS world (that's where I have the idea from - and yes, it still works even though the article is from 2011).
I'm using jQuery to sort a column of emails, though they are base64 encoded in js... so I need a regex command to ignore the <script>.*?<script> tags and only sort what is after them (within the <noscript> tags).
Column HTML
<td>
<script type="text/javascript">
document.write(Base64.decode('PG5vYnI+PGEgaHJlZj0ibWFpbHRvOmJpY2VAdWNzYy5lZHUiIHRpdGxlPSJiaWNlQHVjc2MuZWR1Ij5iaWNlPC9hPjwvbm9icj48YnIgLz4K'));
</script>
<noscript>username</noscript>
</td>
Regex that needs some love
a.replace(/<script.*?<\/script>(.*?)/i,"$1");
Assuming that the structure of the html doesn't change, you can use this:
$(a).contents().filter(function(){
return this.nodeType === 3
}).eq(1).text();
It gets all text nodes and then filters to the one at index 1 and get's it's text value.
And if you want to stick with regexp, here's one:
a.replace(/(<script type="text\/javascript">[^>]+>|<noscript>.*<\/noscript>)/ig,"");
I know this isn't exactly what you're asking for (though I'm a little confused what you're asking for, to be honest...), but have you looked at using document.getElementsByTagName('noscript')? This function should return an array, the first element of which will be your noscript element.
Also, I'm not really clear on your overall approach to this problem, but it seems like you're misunderstanding the purpose of a noscript element. noscript elements only execute when the browser does not support Javascript, which means the only time noscript content would be displayed to the user is when the Javascript that you're using to modify the noscript content wouldn't run.
Perhaps you could clarify what exactly you're trying to do?
Often times, when I use struts 2 tags, the loading of a page will be incomplete apparently because of single quote or double quote characters from the struts 2 tag interfering with such characters from javascript.
One example I am very eager to get working is as follows:
var me = '<s:a href=\'http://www.google.com\'>Google Link</s:a>';
$('#appnSelect').html(me);
So what I am concerned about is when single and double quotes are inside that me string on the right side of line 1. Ultimately, I need to get <s:select> to work, but this problem seems to creep in with a number of tags like the above example. Replace the <s:a> tag with an <a> tag, and voila, it works. However, when the <s:a> tag gets expanded, the page will incompletely load.
Is there an easy solution somewhere I am missing? One thing I did try was with the theme attribute setting theme="simple" because sometimes that helps me when the output gets rendered incorrectly. That did not work in this case.
Generating HTML from tags like that in the middle of a JavaScript string constant is always going to be an ugly business. In addition to quote characters, you're also likely to get newlines. Strictly speaking you don't know what you're going to get, and you can't control it.
One thing that comes to mind is that you could drop the tags into dummy <script> blocks marked as a non-JavaScript type:
<script id='anAnchor' type='text/html'>
<s:a href='http://www.google.com'>Google Link</s:a>
</script>
The browser won't try to execute that. You can then do this in your JavaScript code:
$('#appnSelect').html($('#anAnchor').html());
What should work with very little thinking:
<s:a id="google" style="display: none;" href="www.google.com">Google Link</s:a>
Now just grab the the element using the id in your script. Might be better if you set up a class. There are id, style and class attributes for all struts2 tags.
I believe the issue is with your escaping of the single quotes inside the <s:a> tag. In my experience with using <s:url>, I've done the following:
var url = "<s:url value='/someAction.action' />"
I believe the same syntax should hold true for <s:a>.
Additionally, look in your JSP container's error log, and see if you can find an error relating to that <s:a> tag. That may provide some additional insight to the problem.
This is my answer, which will not be the best answer because Pointy's response pointed me in the correct direction. However, up votes still appreciated :)
First, you need the script blocks which are not rendered. I have 2 because a checkbox will toggle between which one is displayed:
<script type="myType" id="abc">
<s:select name="selectName" list="#list1" listValue="%{prefix + '-' + name}" theme="simple"/>
</script>
<script type="myType" id="abc2">
<s:select name="selectName" list="#list2" listValue="%{prefix + '-' + name}" theme="simple"/>
</script>
Next, I create a region which is blank in the html code
<div id="innerRegion">
</div>
Then, I need to put something on the screen when the page first comes up, so go with this:
<script type="text/javascript">
$(document).ready(function(){
$('#innerRegion').html( $('#abc').html() )
});
I needed to put this at the end of my document because onLoad was already being used by a parent page. So I am saying abc is the correct default.
Then I need logic to handle what happens when the checkbox is pushed:
var buttonPressed = false;
$(window).load(
function()
{
LocalInit();
});
function LocalInit() {
$('#myForm input[name=buttonValue]').change(
function()
{
buttonPressed = !buttonPressed;
if (buttonPressed == true)
{
$('#innerRegion').html( $('#abc2').html() )
} else
{
$('#innerRegion').html( $('#abc').html() )
}
$('#dataId').href = document.location.href;
}
);
}
I think what was tripping me up ultimately was that I was trying to force the s:select tag through jQuery functions when as you see above it did not turn out to be necessary. I could just write the s:select as normal.