Is it possible to dynamically set a Spring MVC portlet:actionURL portlet:param using javascript? I have tried with the following code, but the id value always comes across as null to the controller. I have verified that setting the portlet:param manually passes the value correctly:
<portlet:param name="id" value="2" />
I have also verified the value in the javascript is being set correctly and is not null.
(Note: I've changed the variable names, etc. from the original code to simplify it and obfuscate it since it is my employer's code.)
JSP:
<portlet:actionURL var="modifyURL">
<portlet:param name="do" value="modify" />
<portlet:param name="id" value="${model.id}" />
</portlet:actionURL>
...
<form:form action="${modifyURL}" id="modifyForm" modelAttribute="model">
<form:hidden path="id" id="id" />
</form:form>
Javascript called when the update URL is clicked:
function update() {
document.forms[0]["id"].value = selectedId;
document.forms[0].submit();
}
Controller:
#RequestMapping(params = {"do=modify"})
public void modify(#ModelAttribute("model") Model model,
#RequestParam(value = "id", required=true) Long id,
ActionRequest request, ActionResponse response,
SessionStatus sessionStatus, ModelMap modelMap) {
....
A co-worker figured it out. It looks like you just have to add the parameter to the action within the javascript and not include it in the actionURL or form.
JSP:
<portlet:actionURL var="modifyURL">
<portlet:param name="do" value="modify" />
</portlet:actionURL>
...
<form:form action="${modifyURL}" id="modifyForm" modelAttribute="model" method="POST">
</form:form>
Javascript called when the update URL is clicked:
function update() {
$("modifyForm").action = '${modifyURL}&id='+selectedId;
$("modifyForm").submit();
}
I came across this almost 3 years later, still i found it easier to add a hidden form field and when the action is clicked than to set this value to the hidden field
something like
<input type="submit" id="btn_terminate_cmpn"
value="Terminar campaƱa" onclick="setAction('terminate');">
and the javascript code
function setAction(action){
$("#actionToDo").val(action);
}
The URL generated by the portlet tag is on the server side. Javascript doesn't see the portlet tag. It only sees the actual URL. What your coworker is suggesting would work but it's not a good approach. Here he's just adding the dynamic parameter as a query string parameter which makes it visible to all the portlets on your target portal page. A better solution is to keep a hidden element (text box or something) and set the dynamic value to this hidden element in your onSubmit Javascript hander function.
Related
I have a 'parent' page that is using the following bit of code to pull in a form from a different page on the same domain. There are reasons why I can't just place the form directly on the 'parent'.
<script type="text/javascript">
jQuery("#ai_temp_profile_edit").load(
"https://example.com/form/ #profile-edit-form",
function() {}
).hide().fadeIn(1000);
</script>
The form that is pulled in looks like this:
<form action="https://example.com/form/" method="post" id="profile-edit-form" class="standard-form base" target="hiddenFrame">
<label for="field_1">Name</label>
<input id="field_1" name="field_1" type="text" value="Joey-Jojo Jr. Shabadoo">
<input type="submit" name="profile-group-edit-submit" id="profile-group-edit-submit" value="Save Changes " />
<input type="hidden" name="field_ids" id="field_ids" value="1" />
<input type="hidden" id="_wpnonce" name="_wpnonce" value="a62f8d5fec" />
<input type="hidden" name="_wp_http_referer" value="/form/" />
</form>
When 'submit' is clicked, https://example.com/form/ is opened in a hidden iframe and the user name gets properly saved. This all works well.
I would like the user name on the currently loaded 'parent' page to update via jquery, so that the user has some immediate visual feedback that the name change has taken place.
My approach has been to try and take the value out of the 'field_1' input when 'submit' has been clicked, and pass that variable onto a div in the parent page with an id of 'display_name'.
$(document).ready(function(){
function nameUpdate(){
$("#profile-group-edit-submit").click(function () {
var updateName = $("#field_1").val();
$("#display_name").text(updateName);
});
}
nameUpdate();
});
I've also tried adding window.parent.
before the the #display_name selector section and it didn't change anything.
I've used this approach on another button/div combo on the same page and it works, the difference is that that particular button is in an iframe, not loaded by jquery. So I'm guessing my problem is related to that fact.
I've googled around, but have run out of ideas of how to phrase my question, what to look for, etc...
Any help would be greatly appreciated. Thanks!
Edit: For clarity, the div w/ id #display_name won't update.
Use jquery to handle the form submission.
$(document).ready(function(){
$('#profile-edit-form').submit(function(){
var updateName = $("#field_1").val();
$("#display_name").text(updateName);
});
});
EDIT:
Due to your loading the form dynamically you need to bind the submit function after the load. So...
$(document).ready(function () {
var formLoaded = function () {
$('#profile-edit-form').submit(function () {
var updateName = $("#field_1").val();
$("#display_name").text(updateName);
});
};
$("#ai_temp_profile_edit").load(
"https://example.com/form/ #profile-edit-form",
formLoaded
).hide().fadeIn(1000);
});
If I am understanding it correctly, your problem is "display_name" field is not getting updated with the latest value.
If this is the problem then can you try below thing?
Instead of
$("#display_name").text(updateName);
try using-
$("#display_name").val(updateName);
As per the documentation on jQuery site Val() works well with form Elements whereas text won't.
More on Val() method- https://api.jquery.com/val/#val2
I tried searching the site but could not find an answer to my question.
i am developing a java Struts2 web application.
There are 3 form fields on a jsp page as follows:
(Struts2 tags are being used)
<s:form action="action1">
other fields
......
<s:select name="test1" list="{'A','B','C'}"></s:select>
<s:textfield name="test2"></s:textfield>
<s:textfield name="test3"></s:textfield>
.....
other fields
<s:submit value="submit1"><s/submit>
</s:form>
when a value is selected in test1 field, test2 and test3
would needed to be populated from the database based on the
value selected in test1.
as per the process i need to implement, i need to do some calculations based on the input from jsp1(presented above), and present the result on jsp2 which has to have entirely different content from jsp1. My issue is limited to the data entry in jsp1.
what would be the best way of doing this without javascript?
assume that javascript is disabled in the browsers accessing
the application.
thanks,
EDIT
It seems that there's a bit of confusion here, let's try to make it clear:
There are basically three ways of triggering a communication with the server from the browser:
submit HTML
submit JS
AJAX submit
You may or may not care about giving support to users browsing with JavaScript disabled;
if you DO NOT care, then you can proceed as you wish;
if you DO care, then you have two ways in front of you:
make an unique version of the pages, that works both with and without JS (by using ONLY option "1", "submit HTML");
make the pages working in two possible ways, mutually exclusive: while processing the page, you detect if the user has javascript enabled: if yes, you go with JS (submit or AJAX), if not, you fallback to the non JS solution ( "submit HTML" ).
Both this two solutions works with and without JS, but the latter is generally preferred because you can set up a nice, good-looking, user's experience-oriented WebApp for the 99% of the users, by using JavaScript and eventually AJAX, and create a fallback solution for the 1% of the users that, even if the site won't be nice as in the JS version, and even if it won't have ALL the features of the JS version, it would still be usable, and the core functionalities will be available.
As I said in the comment above, there is no need for the fallback version of the WebApp to be as nice, as fast, as good in user experience as the JS version: it should simply... work.
For example, this JSP will work in both cases: it will do a JavaScript Submit after selecting an element from the Select if JS is enabled, and it will do a submit after pressing the Submit button if JS is disabled.
With JS disabled, onchange will be ignored and <noscript> processed.
With JS enabled, onchange will be processed and <noscript> ignored.
<s:form action="myAction">
<s:select onchange="javascript:document.forms[0].submit();"
name="test1" value="test1" list="{'A','B','C'}" />
<s:textfield name="test2" value="test2" />
<noscript>
<span>
Since you have JS disabled,
you need to manually press to the GO button,
but you still can make it work ;)
</span>
<s:submit value="go" />
</noscript>
</s:form>
in your Action
public class MyAction extends ActionSupport{
private String test1="";
private String test2;
/* Getters and Setters */
public String execute(){
if (test1.length()>0)
assignValues();
return SUCCESS;
}
private void assignValues(){
if (test1.equals("A")){
test2 = "A was chosen, do something";
} else if (test1.equals("B")){
test2 = "B was chosen, do something else";
} else if (test1.equals("C")){
test2 = "C was chosen, what's next?";
}
}
}
The other doubts you are expressing in comments suggest that you may want to step back for a moment and read some Struts2 tutorial, to be sure of gaining the maximum from the framework.
If you have other fields in the same Form that you don't want to be affected, just declare a variable in the Action (with the Getter and the Setter), for each one of them: they will be preserved in the reloaded page, because they will be sent (because they're in form) with the submit, they will be injected through the Setter, they will be read back through the Getter and injected in the new page by the matching with their name and the Action variable.
Otherwise you could use AJAX, but I'd start from this.
And no, you can't nest forms.
Thanks to Andrea Ligios, i have the below solution to my issue.
jsp1 was changed as below
<s:form action="action2">
other fields
......
<s:select name="test1" list="{'Select','A','B','C'}"
onchange="javascript:document.forms[0].submit();"></s:select>
<noscript><s:submit value="populate test2 and test3"></s:submit></noscript>
<s:textfield name="test2"></s:textfield>
<s:textfield name="test3"></s:textfield>
.....
other fields
<s:submit value="submit1" action="action1"><s/submit>
</s:form>
struts.xml has following mappings
.....
<action name="action2" class="MyAction" method="populate">
<result name="success">/jsp1.jsp</result>
</action>
<action name="action1" class="MyAction">
<result name="success">/jsp2.jsp</result>
</action>
.....
MyAction has following code
public class MyAction extends ActionSupport{
//all field declarations
//Getters and Setters
public String execute(){
//do processing for jsp2 based on values from jsp1
return SUCCESS;
}
public String populate(){
//populate test2 and test3 from database based on value of test1
return SUCCESS;
}
}
i have a textarea defined by an id
<textarea id='vegetable'> Tomato </textarea>
i have a button
<button type="button" onclick="MyFunction()">generate vegetable</button>
which trig a javascript in order to modify the content of the textarea
<script>
function MyFunction()
{
document.getElementById("vegetable").innerHTML = VegetableNameGenerator();
}
</script>
The problem is this php action :
<form action="{{ path('mypath', { 'myparam': ??? }) }}" method="post" >
<input type="submit" />
</form>
??? must be the content of the textarea (which is also known by the javascript code) but i don't know how to access it in twig.
I guess there are several way of doing that : jquery, dom, global variable twig... any syntax example would be great.
This is impossible in the way you're describing it.
When a request is made to the server, twig renders the page, then it is sent to the browser, and then javascript can run.
There are options for how to make this work:
Create a controller action which returns the rendered path when you call it using a GET request with the provided parameter. Then create an event listener on the submit button that blocks the submit process until it has retrieved the route via AJAX and modified the form's action attribute.
Redirect from your controller to the path you want displayed. myparam will be included in the post data, so you can redirect from your controller action after you've handled the form.
$this->redirect($this->get('router')
->generate('mypath',
array('myparam'=>
$this->getRequest()->get('myparam')
),
true);
I want to have a JSP like this:
<form id="form1">
Name is: <%=request.getParameter("name") %>
Show Email Form
</form>
<form id="form2">
<input type="text" name="emailid" />
Submit
</form>
My javascript is something like this:
function fun1() {
//Nothing important here, just show second form
$('#form2').show();
}
function fun2(myemail, myname) {
//Do something important here,
//Like update email for the given name
xmlhttp = GetXmlHttpObject();
var url = "updateEmail.do?email=" + myemail + "&name=" + myname;
xmlhttp.open("POST", url, true);
}
Things to note here:
1) There is no action tied to my form, I am submitting the second form through Ajax.
2) I need to have two different forms, first form has more elements besides Name. And the second form has another different set of elements besides the email. Only one of the functions (fun2) in form2 needs both parameters of the name from form1 and email id from form2.
3) Form1 has an uneditable name parameter, and form2 has an editable email parameter. The onclick function in form2 picks up the email text input with jQuery.
4) One other scenario to consider is if there are multiple entries of name in form1, like a list of names using loops. Eg,
<form id="form1">
<logic:iterate id="record" name="peoplerecords" property="records">
Name is: <bean:write name="record" property="name">
')">Show Email Form
</logic:iterate>
</form>
What is the best way to write the name parameter from form1 into the javascript onclick url in form2?
form1 :- onclick="fun1(name);"
form2 :- onclick="fun2(email, name);"
You can either directly put the name in with JSP:
Submit
Or you can give the dom node containing the name an id and access it with jQuery
Name is: <span id="nameNode"><%=request.getParameter("name") %></span>
Submit
Also consider getting the required parameters directly in your functions or define the onclick handlers in your script section to avoid the code getting messy. Watch out for the quotes inside HTML attributes, you used single quotes twice in the second onclick handler.
Don't put 'data' in your HTML model.
If you're using a server-side language, pass in all the data directly into your inline scripts, not inline HTML.
Example:
<a onclick="alert('<?php echo $the_string;?>');">alert!</a>
vs
<a id="alert_link">alert!</a>
<script type="text/javascript">
var the_string = <?php echo json_encode($the_string);?>; // you get javascript safe encoding with json_encode, almost for free!
document.getElementById("alert_link").onclick = function () {
alert(the_string);
};
</script>
The second example may seem like a lot more code but it really pays off if you have many of these things.
At this point, all your data is available in JavaScript, so it should be easy to tie it all together.
since your name value is being written in from the server (in JSP), can you just write it directly into your fun2 call?
onclick="fun2('$(\'input[name=emailid]\').val()', '<%=request.getParameter("name") %>')"
I have the following code:
$('#CreateButton').click(function (event) {
var datastoreValue = $("#SelectedDatastore").val();
window.location = "/Q/Create?datastore=" + datastoreValue;
});
It works good but I would like to have the datastore=XYZ hidden from my user. Is there another way that I can pass this information so I would be able to read it in my MVC controller. Currently I read it like this:
public ActionResult Create(string datastore)
{
When inside this method the value of datastore is available to me.
Surround you code with a form tag with a method set to POST. Also add HttpPost attribute above your Create action. This will post the data to your action without client seeing the query string value. If you are posting to another action that specify that in your action attribute inside form. For example,
<% using (Html.BeginForm("Create", "MyController", null, FormMethod.Post)) { %>
<%: Html.Label("Data store value: ")%>
<%: Html.TextBox("datastore") %>
<input type="submit" value="Submit" />
<% } %>
Your Create action will pick this up and do the rest.
Hope this helps,
Huske
You could put the datastore value in a cookie to hide it from the user, though cookies are best used for settings that you want to last awhile, not settings that are meant just for one page.
Or, you could use a Post and put the create information in a hidden form and submit that.
Or, you could use an Ajax call to issue the create and then change the page yourself afterwards.
Otherwise, the query parameter like you are using is a standard way of specifying page-level parameters for a new page.
If you stay on the same website, you can post your data to your controller; it will pick up the data from the post collection and your url won't display the query string parameters.
Just wrap your form with the control whose id is SelectedDataStore in a tag with the action set to your url and the method set to post
Here is one quick example with a submit button:
<FORM action="/Q/Create" method="post">
<INPUT id="SelectedDataStore" />
<INPUT type="submit" value="Send">
</FORM>