Passing values as bash file arguments through a JSP page - bash

I am writting this code for a JSP page that reads from an text input and passes the variables' values to a bash file as parameters, but it seems like the bash file doesn't take variables, it only worked when I passed real values instead of variables.
How to pass a variable to this bash file?
Here is the code:
<%
String myArgument = "";
if (request.getParameter("submit")==null)
{
%>
<form method="POST" action="/tomcat/webapps/project/jsp/runCMD.jsp" id=form2>
<input type=text id=first value="${first}" Title="IP adress here" >
<input type="submit" value="Submit Changes" name="submit"
onClick="if(runOnSubmit()){getSomethingWithAjax('ChangeIP.jsp'+
getAllFormElementsAndMakeIntoURI(true),'',
'hereIsTheMainHeaderSpan',false,false);}">
<%
}//end if
//else if submitted
else {
request.setAttribute("myArgument", myArgument);
try {
Process p = Runtime.getRuntime().exec("/root/script.cmd myArgument );
p.waitFor();
System.out.println("Waiting for the System to reboot" + p.exitValue());
} catch (Exception e) {
System.out.println(e.getMessage());
out.println("There was an error while submitting ");
}
}//end else
%>
Note that when passing a value to the script it got executed with the code below:
Process p = Runtime.getRuntime().exec("/root/changeip.cmd 10.0.100.18");

What you want is:
Process p = Runtime.getRuntime().exec("/root/script.cmd " + myArgument );
P.S.
Actually I don't see where do you assign a value to myArgument after declaring it:
String myArgument = "";
Not really related, but you are doing it kind of PHP style. Read this: https://stackoverflow.com/a/3180202/814702

Related

<g:remoteForm> redirect is not happening

I am using a to handle a login. In the case of incorrect credentials, I use Ajax to print an error message on the same web page but in the case of success I would like to forward to another web page. What is happening is that even in the case of success it is printing results on the same page. I know that this has partially to do with the fact that you can't send a redirect to Ajax. However, still a newbie to know how to go about it. Any suggestions?
Here is my gsp section having to do with this form:
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" update = "error_message">
<br><br><label>User Name (email): </label><g:textField name = "username" /><br><br>
<label>Password: </label><g:field name = "password" type = "password" /><br><br><br><br>
<div id = "error_message" style = "text-align: center"> </div>
<div style = "text-align: center">(for TWC employees only)</div>
<g:submitButton id = "submit_button" name="Submit"/>
</g:formRemote>
and here is the controller method 'authenticate':
def authenticate = {
try {
MongoClient mongoClient = new MongoClient("localhost", 27017)
DB db = mongoClient.getDB("admin");
def userName = params.username
def passWord = params.password
boolean auth = db.authenticate(userName, passWord.toCharArray())
if (auth)
redirect (action: loggedin)
else {
render "Login or Password incorrect!"
}
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch (MongoException e) {
e.printStackTrace();
}
}
def displayerror = {
render "Login or Password incorrect!"
}
def loggedin = {}
As it is, I can't get the gsp corresponding to the 'loggedin' method to display. Any ideas?
Minor adjustments needed to previous poster's most helpful suggestions. This is the code that will actually solve the issue.
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" onSuccess="doResult(data)">
<br><br><label>User Name (email): </label><g:textField name = "username" /><br><br>
<label>Password: </label><g:field name = "password" type = "password" /><br><br><br><br>
<div id = "error_message" style = "text-align: center"> </div>
<div style = "text-align: center">(for TWC employees only)</div>
<g:submitButton id = "submit_button" name="Submit"/>
</g:formRemote>
javascript below:
function doResult(data) {
if (data.success == true) {
window.location.href = data.url;
} else {
$("#error_message").html(data.message);
}
}
controller code section below
//success case
render(contentType: 'text/json') {
[success: true, url: createLink(controller: 'whateverController', action: 'whateverAction')]
}
}
else {
render(contentType: 'text/json') {
["success": false, "message": 'Login or Password is incorrect.']
}
importing JSON converter in last set of code isn't needed either.
You are correct that you can't send a redirect using ajax. What you can do, however, is send something back in your ajax response that you can read and redirect if needed.
Instead of just updating the div with the response from your ajax call you will need to send back some JSON data and use the onSuccess attribute of the formRemote tag to pass the results to a function which can act accordingly.
I would suggest you start by reading over the documentation for the formRemote tag, then consider something like the following:
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" onSuccess="doResult(e)">
<br><br><label>User Name (email): </label><g:textField name="username" /><br><br>
<label>Password: </label><g:field name="password" type="password" /><br><br><br><br>
<div id="error_message" style="text-align: center"> </div>
<div style="text-align: center">(for TWC employees only)</div>
<g:submitButton id="submit_button" name="Submit"/>
</g:formRemote>
Notice in the above that onSuccess is now set on the formRemote tag and update is removed. The response from the form submission will now be passed to the javascript function doResult.
This is what the function might look like:
<script>
function doResult(response) {
var result = eval('(' + response.responseText + ')');
if (result.success == true) {
window.location.href = result.url;
} else {
$("#error_message").html(result.message);
}
}
</script>
The only thing left is to change how your controller responds to the form submission. First you will need to add the import for import grails.converters.JSON into your controller. Then change the way it responds. It might look like this:
import import grails.converters.JSON
...
// in the case of an error
render [success: false, message: "Login or Password incorrect!"] as JSON
return
...
// in the case of success
render [success: true, url: createLink(controller: 'whateverController', action: 'whateverAction')] as JSON
return
It may seem like a lot to take in all at once, but once you do it a few times it becomes quite simple. One thing that helps a lot is to read the Grails documentation. It's long, but it's very well written and will help a lot.

If search don't return values from database show an empty form

So i got a page that have a search form, and when the user search for a value if there are no records on database the form returns empty, but if there are records the form is populated with data.
What i was thinking was this
var db = Database.Open("myDataBase");
var selectCommand = "SELECT * FROM exportClient";
var searchTerm = "";
if(!Request.QueryString["searchField"].IsEmpty() ) {
selectCommand = "SELECT * FROM exportClient WHERE clientAccount = #0";
searchTerm = Request.QueryString["searchField"];
}
if(IsPost){
var selectedData = db.Query(selectCommand, searchTerm);
}
And Then:
<body>
<div class="col_12">
<form method="get">
<label>search</label><input type="text" class="col_3" name="searchField" />
<button type="submit" class="button red" value="search">search</button>
</form>
</div>
#if(!Request.QueryString["searchField"].IsEmpty() ){
foreach(var row in db.Query(selectCommand, searchTerm)) {
<div class="col_12 box">
<form method="post">
// HERE IS THE FORM POPULATED
</form>
</div>
}
} else {
<div class="col_12 box">
<form method="post">
// HERE IS THE FORM NOT POPULATED
</form>
</div>
}
</body>
But what is happening is that the form that is not populated is always showing up when i enter the page, and i need that the only thing that user see when enter the page is the input field to do the search.
What am i doing wrong ?
I'm not sure of having understood your goal, but in my opinion your main problem is to detect if either exists or not a query string.
I think that your code should be like this
#if(Request.QueryString.HasKeys())
{
if(!Request.QueryString["searchField"].IsEmpty() ){
<p>searchField has value</p>
} else {
<p>searchField hasn't value</p>
}
}
There are a number of potential issues I can see with your code, hopefully you can put these together to achieve what you wanted:
As Selva points out, you are missing the action attribute on your forms.
The selectedData variable you create inside your IsPost() block goes out of scope before you do anything with it. Perhaps you didn't include all your code though, so ignore this if it just isn't relevant to the question.
To answer the main question: if you don't want the empty form to appear when the user hasn't yet performed a search, surely you just need to completely remove the else block - including the empty form - from your HTML?
Hope that helps.

How do i reuse the expression from HtmlHelper.EditorFor

In my cshtml file i have the following call
#foreach( var EducationPlan in Model.Fields) {
#HtmlHelper.EditorFor(m => EducationPlan, "ViewFieldInputWithHidden")
}
and in ViewFieldInputWithHidden.cshtml i have
#HtmlHelper.TextBox(Model.MemberName, Model.Value, Model.HtmlAttributes)
#HtmlHelper.Hidden(Model.MemberName, Model.Value, new { id = Model.MemberName + "_Hidden" })
This gives me, with unimportant stuff removed
<input id="EducationPlan_ResponsiblePerson" name="EducationPlan.ResponsiblePerson" type="text">
<input id="ResponsiblePerson_Hidden" name="EducationPlan.ResponsiblePerson" type="hidden">
Is there any way to emulate/use the same value as the TextBox uses to get the "EducationPlan" string with me when i write the id? Or is there, even better, just a way to append the "_Hidden" to the id.
I found the solution and i'm leaving it here for other who runs into the same problem.
Replacing the hidden with the following code helped:
#Html.Hidden(Model.MemberName, Model.Value, new { id = Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(Model.MemberName) + "_Hidden" })
So, basically the TemplateInfo class saves the expression in some way.

AngularJS Form Validation inside an ng-repeat

So I am trying to validate the input of one item inside of an ng-repeat. For examples sake lets say that I have 5 items (1,2,3,4,5) and I only want to validate the form if the 4th item is selected.
I have used ng-pattern before to validate forms, but not one that had a dropdown menu to select item.name
I have included the regex I would like the 4th item to be validated with inside the ng-pattern.
<div>
<select name="name" ng-model="item.name" ng-options="item for item in items" required></select>
</div>
<div>
<input name="results" type="text" ng-model="item.results" ng-pattern="/^\d\d\d\/\d\d\d/" required>
</div>
Any suggestions as to the correct way to validate this situation would be greatly appreciated. I have thought about creating a directive to validate this, but that feels like is an overly complicated solution to this since I would not use the directive more than once in this app.
//////////////////////////////////////////////////
It wouldn't let me answer my own question so here is the answer I figured out.
What I ended up having to do was use ng-pattern and pass it a function.
<input name="results" type="text" ng-model="vital.results" ng-pattern="vitalRegEx()" required>
Here is the controller code
$scope.item4RegEx = /^\d{2,3}\/\d{2,3}$/;
$scope.itemRegEx = function() {
if($scope.item && $scope.item.name === "fourth item")
return $scope.item4RegEx;
else return (/^$/);
};
or else...
add ng-change directive on the select dropdown which calls a Controller method and that controller method sets a flag whether to validate form or not.
eg.
<select ng-change="checkIfFormShouldbeValidated()" ng-model="item.name"></select>
// Inside controller
$scope.checkIfFromShouldBeValidated = function(){
if( $scope.item.name == 4th Item ) $scope.shouldValidate = true;
else $scope.shouldValidate = false;
};
$scope.formSubmit = function(){
if(($scope.shouldValidate && form.$valid) || (!$scope.shouldValidate)){
// Submit Form
}
};
See if it helps.
I wrote this recursive function inside my controller to check the validity of all child scopes.
function allValid(scope) {
var valid = true;
if (scope.$$childHead) {
valid = valid && allValid(scope.$$childHead);
}
if (scope.$$nextSibling) {
valid = valid && allValid(scope.$$nextSibling);
}
if (scope.scorePlannerForm) {
valid = valid && scope.myForm.$valid;
}
return valid;
}
Then in my controller I check this with the controller scope.
function formSubmit() {
if (allValid($scope)) {
// perform save
}
}

:remote form with multiple submit buttons

I can't seem to get a :remote form with multiple submit controls to work under Rails 3. The following code:
<%= form_tag({:action => 'debug'}, {:remote => true}) do %>
<%= submit_tag "Foo" %>
<%= submit_tag "Bar" %>
<% end %>
Produces a form with two buttons, but the resulting AJAX POST doesn't contain a commit parameter to say which one was pressed. If I leave :remote => true out, the normal POST does contain the commit parameter.
Is there any way to make this work, or is it just a bug?
After some playing about, I think I've found a solution.
The problem is that rails.js uses serializeArray() on the form element containing the clicked submit control; but the form's serialized data doesn't contain that control. However, JQuery or Javascript is keeping track of the original event in the call-chain, which was technically a "submit" event on the appropriate control.
So I've edited rails.js as follows:
callRemote: function (e) { /* Note - new parameter e */
var el = this,
method = el.attr('method') || el.attr('data-method') || 'GET',
url = el.attr('action') || el.attr('href'),
dataType = el.attr('data-type') || 'script';
if (url === undefined) {
throw "No URL specified for remote call (action or href must be present).";
} else {
if (el.triggerAndReturn('ajax:before')) {
var data = el.is('form') ? el.serializeArray() : [];
/********************/
/* Note new if-test */
/********************/
if (e)
{
data.push({name: e.originalEvent.explicitOriginalTarget.name,
value: e.originalEvent.explicitOriginalTarget.value})
}
/* Function continues as before */
... and further down ...
$('form[data-remote]').live('submit', function (e) {
$(this).callRemote(e);
e.preventDefault();
});
This has the effect of adding in the name-value pair of the clicked button before firing off the AJAX.
I'm a bit new to Javascript, so do let me know if any of this is horrendously wrong!
I tried your solution and it worked for Firefox, but then the application did not work any more for IE and Safari. Now I found another solution: Simply putting the value of the submit button into a hidden input field by a small javascript.
<input id="selected_button" type="hidden" name="commit" value=""/>
<script>
function identify_button( el ) {
window.document.getElementById( 'selected_button' ).value = el.value;
}
</script>
<input class="button"
type="submit"
name="commit"
value="Save"
onclick="identify_button( this )" );"
/>
<input class="button"
type="submit"
name="commit"
value="OK"
onclick="identify_button( this )" );"
/>

Resources