This is the script I have in my gsp page:
<script>
function getItemsLength(){
var id = document.getElementsByName("franchiseID")[0].value();
alert(id); //This displays the intended id
var itemLength = ${storeCommand.numOfBranches(id)}; //The id becomes null when sent here
}
</script>
This function is called onclick for a button, I cannot access the id through the store command itself, since the page hasn't been saved yet - it appears as null. Essentially I take in an ID the user gives me for the franchise, and I query to see how many stores have that franchiseID to display it on the screen.
I am new to grails and web development, so let me know if there is anything I am doing wrong!
The fundamental issue you have here is you are trying to mix client-side programming and server-side programming. ${storeCommand.numBranches(id)} is processed when the HTML is rendered and in that case id is not in scope.
Related
I tried to access the my C# method in my JavaScript, but this method is not accepting the local parameters and saying, the parameter does not exist in the current context.
var typeofServiceNumber = $("#serviceType").val();
#MyStaticClass.StringEncoding(Convert.ToString(typeofServiceNumber));
The above typeofServiceNumber is not recognized by the method
Razor code is executed server side before the HTML is returned in the response stream.
Javascript is executed client side within the resultant HTML.
Therefore you cannot pass a Javascript variable through to a Razor method, and you receive the message that typeOfServiceNumber is not recognized.
To be recognized, it would either need to be handled server side via data being passed to the View (ViewBag, Model etc), or it would need to be declared and assigned to within Razor tags on the page itself.
EDIT: to clarify the last point:
var typeofServiceNumber = $("#serviceType").val();
#MyStaticClass.StringEncoding(Convert.ToString(typeofServiceNumber))
The first line you have here is all happening in the browser of the end user.
The second line is all happening on the server. You see the error message because you are trying to pass "typeofServiceNumber" to your method, and the variable isn't even declared at that point.
Without knowing exactly what you're trying to achieve it's hard for me to give a precise answer as to how to solve your problem. But here are two possibilities:
1) You know what $("#serviceType").val() is going to be before you serve the web page to the end user because that value is being set server side.
Controller:
public ActionResult MysteryController()
{
...your code here to work out what the service type is...
ViewBag.serviceType = serviceType;
return View();
}
View:
...lots of lovely html and such...
<script>
#MyStaticClass.StringEncoding(Convert.ToString(ViewBag["serviceType"]));
</script>
I can't see what the output of #MyStaticClass.StringEncoding() is but I have to assume at this point that it is doing whatever it is supposed to do.
Although the logic is split between the controller and the view, all of this is happening server side.
The second half of my point "or it would need to be declared and assigned to within Razor tags on the page itself." refers to the fact that one variation of this method could involve manipulating data in the View itself by enclosing it in a Razor code block like this:
#{
var typeofServiceNumber = #MyStaticClass.StringEncoding(Convert.ToString(ViewBag["serviceType"]));
}
The alternative, which I did not really address originally is:
2) You don't know what the value of $("#serviceType").val() is going to be before the page is loaded because it is being set by the end user and your function needs to be used before the data is submitted to the server:
If that's the case then #MyStaticClass.StringEncoding(Convert.ToString(typeofServiceNumber)) is no good to you, you will have to replicate the function in JavaScript and include it in the webpage itself.
My client has decided to migrate to Office 2016 and porting portions of a business process to that client requires us to offer a replacement to the Document Information Panel, which is no longer available. The Backstage file information area isn't considered a sufficient user experience for the users in question, so we're endeavoring to replace the DIP with a Task Pane app.
This example: https://www.youtube.com/watch?v=LVGqpns0oT8&feature=share shows that the idea is, at least in theory, possible. We considered buying this app but can't find sufficient information to do so.
So we set about attempting to replicate the functionality we need in the DIP. It appears that we can successfully set Document Properties of standard types, such as strings, which looks something like this:
Word.context.run(function(context){
var properties = context.document.properties;
context.load(properties):
return context.sync().then(function(){
properties.title = properties.title + " Additional Title Text"; // once the sync goes off, this works.
return context.sync();
});
});
However, when we try to update an Document Property that's, for example, a Managed Metadata property defined by a SharePoint content type, the value in the proxy object loads and remains changed, but it seems to break its relationship to the actual document property. The code below demonstrates:
Word.context.run(function(context){
var properties = context.document.properties;
var customProperties = properties.customProperties;
context.load(properties):
context.load(customProperties);
return context.sync().then(function(){
var managedMetadataProperty = customProperties.getItem('MngdMetadata');
properties.title = properties.title + " Additional Title Text"; // once the sync goes off, this works.
context.load(managedMetadataProperty);
return context.sync().then(function(){
console.log(managedMetadataProperty.value) // let's say this looks like "10;#Label 1|64d2cd3d-57d4-4c23-9603-866d54ee74f1"
managedMetadataProperty.value = "11;#Label 2|cc3d57d4-4c23-72d4-3031-238b9100f52g"
return context.sync(); // now the value in the javascript object for managedMetadataProperty is updated, but the value in the document does not change.
});
});
});
The document property Managed Metadata Property never changes in the Word UI, nor does a change push back to the SharePoint. Say we save and close the document after making the update, then re-open it. The Property value has not visibly changed, however when we load the proxy object with 'context.load()', the value that's available reflects the changes we made on last run.
I'm unclear about why this would be. It seems like to circumvent this, I would need to make a call back to SharePoint to update the relevant field, but I don't know how I would instruct Word to refresh with the new information from SharePoint.
That's a great question.
The custom properties API gives you access to some built-in properties as well as custom properties. SP-related properties do NOT follow in this category from the API perspective. (and the same is true in VBA/VSTO/COM) To access those you need to use the CustomXmlParts functionalities. Here is a good example on how to use it in the Javascript API.
Also, FYI, the team is working right now in a feature to enable the DIP again, i don't have concrete dates or commitment, but you might get this functionality again out of the box soon.
Have you tried customPropertyCollectionObject.add(key, value) ?
It will replace existing kvp's in the customPropertiesCollectionObject.
Here is the documentation customPropertiesCollection
So, I have to check the status of an action started by the automation script using another automation script. In order to track the action, I have to capture its Id and write it to a file which can be then read by the second script to look for the action. The problem I am having is that I am unable to get the action Id which is a number using getText(). Instead, I keep seeing other non sensical text when I check the content of the file or the variable to which I first store the Id.
The html code for action Id is:
<dd class="ng-binding">232</dd>
I am trying to capture the Id (#232 here) like this:
var Id = element(by.xpath('html/body/div[1]/div[2]/div/div[2]/div/div[2]/div[3]/dl/dd[1]')).getText();
Upon executing the automation script, the console output shows this for the var Id:
Id:[object Object]
I have verified using protractor elementExplorer that xpath points to the right element and can even extract the Id and displays it on the screen correctly. It just does not work when I am trying to store the same Id to a variable and then write to a file so that I can retrieve it for later use. Any help or hints on how to do this would be greatly appreciated.
getText() returns a promise, you have to resolve it, using absolute xpath is a bad way of locating elements. Have you tried locating with cssSelector?
element(by.css('dd.ng-binding')).getText().then(function(text) {
console.log(text);
});
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.
First I would like to say that I searched and found plenty of answers and even tried a couple (more than...) but to no avail! The error is probably mine but it is time to turn to SO and ask.
Problem description: I have a variable that I want to change the value through the user input (click on btn). As soon as the user chooses the btn it will navigate to a different page that will use the result of the variable to perform certain actions. My issue is that if I alert on my 1st page I get the value being passed by the btn... But on the second page I only get "undefined"
I think it has to do with variable scope and the fact that (I think it works that way anyway) even a window.var will be deleted/purged in a different window.
Anyway, the code is something like this (on the 1st page/file):
var somAlvo;
$('#omissL').click(function(){
somAlvo = 'l';
window.location.href='index_ProofOfConcept_nivel1.html';
});
And on the "receiving end" I have the following code
<head>
...
<script type="text/javascript" src="testForm_javascript.js"></script>
to "import" the js file with the variable and:
var processo = somAlvo;
alert(processo);
I tried declaring window, not using var inside the function and so on...
This is a proof of Concept for a project in my local University, where I'm working as a research assistant (so, this is not homework ;) )
Thanks for any help/hints...
You are right in that when you navigate to another page, the entire JavaScript runtime is reset and all variables lost.
To preserve a value across page loads you have two options:
Include it as part of a query string when navigating to the new page.
Set a cookie.
You may also want to look into loading the new content through an AJAX call and replacing what is displayed. This way you won't reload the entire page which won't cause the JavaScript runtime to be reset.