I have a method that is set dynamically to different textboxes in my form. But the problem is that i only want the method to work if i am on my view called riskscore.cshtml. It there a way? like a if(page == riskscore.cshtml){ do method} kind of code?
JavaScript typically has no way of knowing if or when a particular view file was used server-side. It only knows the results that the view rendered.
You can wrap the contents of the view in say a <div class="riskscore">, then select textboxes within those:
$('.riskscore :text')...
You also mentioned in a comment that other elements won't exist without this view. You can use them as your condition, checking whether they exist:
if ($('.other-elements').length) {
// do method
}
Replace '.other-elements' as needed.
You can test URLs in JavaScript:
if(/\/riskscore\.chtml$/.test(window.location.pathname)) {
// You're on riskscore.chtml... Do something
}
you can use window.location to get the current location. or you can use location.pathname to current path.
link here
I think it will help
Related
I am trying to find out what the safest way to store data for use when the user clicks on a button.
I know that you can store data in attributes(either the value attribute or a data- attribute) of the button tag like so:
<button type="button" value="1" data-value="1">Click me!</button>
But the problem with this is that the user(probably really only advanced users) can manipulate the value with firebug or some other app and THEN click the button and send over different data. I fully understand that I need to check the input before I try to do anything with the sent data.
I also found out that I could use jQuery's .data() to attach data to dom elements, which seems a bit more useful. I'm not exactly sure how the data is stored, but I assume its harder to manipulate.
What got me really interested in this question was when I was looking through Soundcloud's code in firebug, I saw that none of the "like" buttons had data attached to the buttons. I tried deleting/manipulating elements/data and the buttons still worked. So it got me thinking that they are probably using a similar process to what jquerys data() is doing.
I just want to know if there is a safer way to store data or a way so that the user can't manipulate the data before clicking the button.
Consider this function:
function setupPrivateData(element) {
var private = 1;
element.setPrivate = function ( d ) { private = d; }
element.getPrivate = function ( ) { return private; }
}
When called with some DOM element it will add two methods to it: .setPrivate(val) and .getPrivate().
These are the only methods that will allow you to access and modify that private variable associated with the element.
The user can always manipulate data. Nothing stops an advanced user to access object properties or call a jquery.data() on their own.
Something you could do in vanilla js would be:
var div = document.getElementById("test");
div.something = "hidden value";
div.addEventListener("click", function() {
alert(this.something);
});
<div id="test">click me</div>
The best way would to be a serverside verification if the sent data is valid or not.
Besides that, you could try to wrap your code in an anonymous function to deny the user access to the object:
(function() {
var data = {};
data.something = "test";
})()
But even that fails as soon as the user manipulates your files and adds for instance a debugger statement.
You can obfuscate your javascript but the only validation has to be done on your server. For example, I tried to get the weather from theweathernetwork. They have hidden their API call using multiple files and callbacks. In my opinion, it's just more challenging (funnier) if you want to reverse-engineer their site.
Javascript can't be secure. Never trust user input
If you are logging button clicks, the safest way to keep track is to save and validate on the server side.
For example, when you click a like button on Soundcloud, it makes an HTTP request to Soundcloud's server, records that you clicked the button, and marks it as a favorite. This way, if the same user clicks the button anytime in the future, it can check before incrementing the number of favorites.
The number displayed in the button is also pulled in from the database when the view is rendered.
This is a huge topic, and you have a lot to learn, far too much for a comment here. Anything "stored" in an attribute in the HTML source is absolutely not secure, it can be changed very very easily.
The most common way of dealing with this would be to use a cookie, but even with some effort these can be manipulated.
If security is important, find some way of identifying your users (possibly by IP, but even that isn't fool proof!) and keep the data on your server, linked to a user ID which can be retrieved after the button is clicked.
I want to attach a jQuery plugin function to an element on my site that exists only on one page. Currently, I'm using this conditional to prevent triggering the limiter function and throwing an error when there is no #advertiser_co_desc in view.
jQuery(document).ready(function($) {
var elem = $('#charNum');
if ($('#advertiser_co_desc').length) {
$('#advertiser_co_desc').limiter(180, elem);
}
});
On my website #advertiser_co_desc is present only on one page.
My solution does the job, but my qualm stems from the fact that the jQuery plugin code as well as the plugin function call presented above (they are both in the same file) get fetched by the browser and the condition is continuously evaluated regardless of whether a user ever gets to a page where #advertiser_co_desc exists.
Is the method I'm using optimal, or is there a better way to attach this particular JS only to the page where '#advertiser_co_desc` exists? Naturally, I wan to avoid adding my scripts in the same file with the PHP code.
Or you can wrap the plugin method as,
var _limiter = $.fn.limiter;
$.fn.limiter = function(limit, element) { // provide complete argmuments
if(this.length) {
_limiter.call(limit, element);
}
};
Make sure that plugin is loaded before this statements.
The best and optimal way to check existence of an element by jquery, is $('#advertiser_co_desc').length that you have used already. So no need to change your code.
I use the window.onload function throughout my website, via a single external .js file, and I usually check to see what page i'm on, so that certain statements will run, e.g:
window.onload = function() {
var curPage = document.getElementById('page').value;
if (curPage === "index.html") {
// do something here
}
if (curPage === "about.html") {
// do something else here
}
}
with 'curPage' being a value from an input within each html document
<input id="page" type="hidden" value="my-page.html" />
I see people adding an id to the body element to achieve the same effect, like so:
<body id="pageisIndex">
However, I would like to know if there is an even better way to initialize/pull a variable within the HTML document without the use of an input or element id.
would something like ...
<script type="text/javascript">
var curPage === 'index.html';
</script>
... be alright/proper to use while also using an external .js file?
EDIT:
All of the answers provided are very good, I believe this is one of those times where it comes down to an individuals opinion; however, using location.pathname or document.URL are great methods that I will be testing out. Awesome!
EDIT 2:
I found something pretty cool I thought I would post here, the following gives us the last page within the path.
page = location.pathname.split('/').pop();
console.log(page);
You could possibly try RegExp with given page name itself without any hidden field:
var url = window.location.pathname;
if(url.match('index.html')) {
//to do
} else if(url.match('about.html')) {
//to do
} else {
//to do
}
You can use:
location.pathname
which returns everything in the url after the domain. For example, for this page it's:
/questions/27956897/window-onload-to-determine-what-code-to-run-depending-on-page-value
It does not include the query string if present.
If you want just what follows the last forward-slash, that's discussed in this post: Get value of a string after a slash in JavaScript, which will work if you don't care about the rest of the path but just want to extract the filename.
I used the last option you have shown which seemed to be a good solution. Setting a variable at the beginning of a page and checking its value is easy. I think instead of giving the exact page name I would go for something which is meaningful like "intropage" or "sellingpage" which will be easier to decipher at a later time.
<script type="text/javascript">
var curPage = 'intropage';
</script>
Another approach that could be to used if you don't want to set id or variable is to check the location.pathname or location.href to get the current location and take necessary steps.
Team,
I am trying to automate a file upload functionality but webdriver doesn't recognize the file object. Here is the thing:
The file object is in a modalbox (xpath is of the modal box is //*[#id='modalBoxBody']/div[1]). The type and name of the file object are file and url respectively.
When i see the html content, there are two objects with the same attributes. One of them is visible and another is invisible. But the hierarchy they belong to are different. So I am using the hierarchy where the element is visible.
Following is my code. I have tried all possible solutions provided in the stackoverflow (as much as I could search), but nothing worked. Commented out sections mean that they too are tried and failed.
wbdv.findElement(By.xpath("//*[#id='left-container']/div[4]/ul/li/ul/li[2]/a")).click();
wbdv.switchTo().activeElement();
System.out.println(wbdv.findElement(By.xpath("//*[#id='modalBoxBody']/div[1]")).isDisplayed()); **//This returns true**
List<WebElement> we = wbdv.findElement(By.xpath("//*[#id='modalBoxBody']/div[1]")).findElement(By.className("modalBoxBodyContent")).findElements(By.name("url")); **//There is only one element named url in this hierarchy**
System.out.println(we.isEmpty()); //This returns false meaning it got the element named url
//((JavascriptExecutor) wbdv).executeScript("document.getElementsByName('url')[0].style.display='block';"); **//This didn't work**
for(WebElement ele: we){
String js = "arguments[0].style.height='auto'; arguments[0].style.visibility='visible';";
((JavascriptExecutor) wbdv).executeScript(js, ele);
System.out.println(ele.isDisplayed()); **//This returns FALSE**
System.out.println(ele.isEnabled()); **//This returns TRUE**
System.out.println(ele.isSelected()); **//This returns FALSE**
ele.click(); **//This throws org.openqa.selenium.ElementNotVisibleException exception**
}
Now, if you look at the 3 methods above, it seems that the element is NOT displayed, NOT selected but IS enabled. So when it is not displayed, selenium cannot identify it. The java script to make it visible also came to no rescue.
Could anyone please help me solve this. It ate my entire day today?
In your last example, it looks to me like you have the right idea with using the 'style.visibility' tag. Another thing that I would recommend trying is using "ExpectedConditions.visibilityOfElementLocatedBy" method. Usually I use "presenceOfElementLocatedBy", but if you are talking about the css visibility property, I think using "visibilityOfElementLocatedBy" is the way to go. I think what might be happening for you is that you need the wait condition on the element object you are trying to get a hold of and the "ExpectedCondtions" method should give you what you need. I see that you have tried a few things but you haven't listed using a Wait condition. No guarantees, but you should try it:
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath(".//whatever")))
I'm trying to get to learn som javascript/jQuery stuff, and I'm really struggling with this one. It's basically a question of structure – how to do things in the best possible way.
I've got this function that randomly picks out a list item from one of three unordered lists (where all list items have been hidden), and shows it. Depending on what page I'm currently on, I would like to select a list item from one list in particular. All my lists are "marked" with an id, to make them unique.
I could pass an argument to my randomize function with the list id of my choice, to make it only select an item from that particular list. However, this would mean that I would have to place inline scripts in the html (one script tag with custom function call for each page), and from what I've heard inline scripts tehnd to block page rendering. And that would be bad, becuase I care about performance. Another way could be to have lots of if/else clauses, such as "if body has class the_classname -> randomize from the list with with id the_id". That would however mean that the script would have to make lots of unnecessary queries on the DOM.
Don't know if there's a term for what I'm talking about. Perhaps something like "conditional function calls" or maybe "page based function calls".
How would you tackle such a problem? I know my CSS & HTML, but am quite new to javascripting. Just trying to do the right thing...
One way would be to create a javascript file that you include in the header of all your pages. The javascript file will contain your function that takes a pageId, and returns a list item based on the page
function getListItem(pageId) {
switch (pageId) {
...
}
}
Assign an ID attribute to the BODY tag of each page, corresponding to the pageId in your javascript function:
<body id="home-page">
Then, on your page load, you can pass in the ID value to your function using jQuery:
<script type="text/javascript">
$(function() {
var listItem = getListItem($('body').attr["ID"]);
} );
</script>
This would pass in "home-page" to your javascript function and return the list item determined by the logic inside your javascript function.
The very best way to do this would be to examine the url (no DOM traversal involved, no additional external scripts, so it's fast):
var path = window.location.pathname;
if (path.indexOf('/a_unique_url') !== -1) {
// do code for the page 'a_unique_url';
} else if (path.indexOf('/another_unique_url') !== -1) {
// do code for the page 'another_unique_url';
} else {
// do default action, because none of the above were found.
}
A little more wordy on your part, but faster if you have a lot of unique operations would be to use a switch statement and the full path, like this:
var path = window.location.pathname;
switch(path) {
case '/full/path/after/domain.html':
// do code for the page '/full/path/after/domain.html';
break;
case '/some/other/path.html':
// do code for the page '/some/other/path.html';
break;
case '/yet/another/path.html':
// do code for the page '/yet/another/path.html';
break;
default:
// do default action, because none of the above were found.
break;
}
Although, if you have access to server side scripting, there are more efficient methods for these kind of operations.
To circumvent the possibility of your scripts holding up the browser it's common practice to place your scripts just before the end of your body tag.
You may even want to look into asynchronous script loading.
Friend, I don't understand exactly what you want, but I'll try to help:
the inline javascript will block your page if you put them alone in the middle of your code, but you can say to them to execute only when the page was loaded with this code:
window.onload = function (){
//call your function with the desired parameter
}
So when your page loads, the function on window.onload will be executed.
Add it from the server-side at run-time: Page.RegisterClientScriptBlock Method
Customize it with a property from the code-behind;
function myFunction() {
var theParameter = '<%# parameterName>';
// do something
}