In my Web-based Task Module I display a button for the user to click if they accept certain conditions. The page has a form element with several hidden inputs to send a POST request to open a web page in a new browser window. When the user clicks the button on the page, we call a javascript function that calls the submit() method on the form and when the submit() completes calls microsoftTeams.tasks.submitTask() with the success results to close the Task Module.
<html>
<body>
<script>
microsoftTeams.initialize();
function buttonClick() {
// have the form submit to open the external document
document.getElementById("openNewDocument").submit();
// tell the bot the user didn't cancel
microsoftTeams.tasks.submitTask(
{"command":"openDocument", "success":"true"},
[ {my App ID} ]
);
}
</script>
<form
id="openNewDocument"
method="post"
action={url to document server}
target="_blank"
>
<input hidden="true" name="docContext" value={encryptedContext} />
<input hidden="true" name="activityId" value={activityId} />
<input hidden="true" name="participantId" value={participantId} />
<input hidden="true" name="tid" value={tid} />
</form>
<button label="open document" onClick=buttonClick()>
Open document
</button>
</body>
</html>
In the web browser the code works just fine. But in the Desktop Teams app (MacOS) the POST request is sent as a GET and the hidden inputs are ignored.
Is there a secret to getting the Form data send as a POST?
Form POST will not work in Task module. You need to call chaining in task module. Please go through this documentation.
Related
When I click the "submit" button, the form is not submitted. Why?
I got it straight from Google's sample code, all I added was one line:
document.getElementById("myform").submit();
The "thanks" message was shown.
If I click the "submit without validate" button, the form is submitted.
<html>
<head>
<script>
function onSubmit(token) {
alert('thanks ' + document.getElementById('name').value);
document.getElementById("myform").submit();
}
function validate(event) {
event.preventDefault();
if (!document.getElementById('name').value) {
alert("You must add text to the required field");
} else {
grecaptcha.execute();
}
}
function onload() {
var element = document.getElementById('submit');
element.onclick = validate;
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form action="/Second/Save" method="post" id="myform">
Name: (required) <input id="name" name="name">
<div id='recaptcha' class="g-recaptcha"
data-sitekey="6LexWMMZAAAAAGpLECkk-pfZ-sYuQ9qDu7wiMJ3M"
data-callback="onSubmit"
data-size="invisible"></div>
<button id='submit'>submit</button>
<button onclick="onSubmit();">Submit Without Validate</button>
</form>
<script>onload();</script>
</body>
</html>
The issue is that you have a button in the form with the id "submit". Any element in the form with a name or an id is reflected in a form attribute with that name. So if you have the form object will have an "elephants" attribute. In this case the submit button is accessible via form.submit, but this masks the submit() function.
If a form control (such as a submit button) has a name or id of submit, this method will mask the form's submit method.
MDN Web docs
Please check your site key, this error is mainly formed when your domain does not match your site key.
You can create your own google captcha key of your domain with your google account it's free of cost from the link given below
https://www.google.com/recaptcha/admin/create
Let's say that I have a page rendered by Spring Framework. It is a page with Angular 2 code. How could I receive data on the page if Spring sends it? I do not want to render a page, then do an HTTP request, then get a response. No, in Spring controller I want to send data and somehow receive it with Angular 2 and show (without additional requests). With JSPs it is obvious how to do, but how to set Angular 2 model from JSON sent by Spring upon rendering the page?
What I have right now is Spring Security managing login. Then, in controller data gets prepared depending on the user, and then I want to send it to Angular 2 page. So, I am stuck with not knowing how to render a page AND attach data for it to be rendered by Angular 2 at the same time.
I'm not sure if I totally understood the question... anyway if I did, I'd do in this way
In spring controller, before rendering the JSP page, i'd all the business logic you need to create the JSON; then I'd create a JSON string and I'd attach it to the model
It means I'd do something like that:
#RequestMapping("/render")
public String renderView(ModelAndView model)
{
//Your JSON String
String json = "{\"foo\":\"bar\"}";
model.addAttribute("json", json);
return "yourJspName";
}
Then in your JSP you can use Angular to access to the json contained in the model (that is in the pageContext); for example, by using JSTL:
<script type="text/javascript">
var theJsonString = '${json}';
</script>
or
<script type="text/javascript">
var theJsonString = '<c:out value="${json}" />';
</script>
At this point you have the JS variable named theJsonString with your JSON string and you can use it as you want... for example by passing it to angular
If you need JSON object you should to something like this:
<script type="text/javascript">
var theJsonString = '${json}';
var theJsonObj = JSON.parse(theJsonString);
</script>
or
<script type="text/javascript">
var theJsonString = '<c:out value="${json}" />';
var theJsonObj = JSON.parse(theJsonString);
</script>
I hope this can help
Angelo
I was able to solve the problem but by redesigning the app and not by finding a real fix. What I was doing is starting Angular 2 app, have some navigation, functionality on the page, then one could click login, and Spring Security came into play. However, after verification I could not figure out how to launch Angular 2 app again: start a completely new one? Or somehow use the already launched to proceed with the development? Not sure.
What I did is just start the app by showing login page always at the very beginning and only after user logs in, Angular 2 comes into play. I guess, I could set up a second website to develop another Angular app, and make a link there that would launch this one, if we need some functionality before user logs in. The problem was that I was trying to split one Angular app into two, I guess.
Just in case, here is my security.xml part (Spring Security version 4.0.4.RELEASE):
<http use-expressions="true">
<intercept-url pattern="/views/**" access="hasAnyRole('ROLE_CUSTOMER', 'ROLE_ADMIN')" />
<form-login
login-page="/login.jsp"
login-processing-url="/views/home"
authentication-failure-url="/login.jsp?error=failed_login"
/>
<logout logout-url="/logout" logout-success-url="/login.jsp" delete-cookies="JSESSIONID" />
<remember-me />
<headers>
<cache-control/>
<xss-protection/>
</headers>
</http>
Login form:
<form class="form-signin" method="POST"
action="${pageContext.servletContext.contextPath}/views/home">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="text" name="username" class="form-control" placeholder="Login" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" name="password" class="form-control" placeholder="Password" required>
<div class="checkbox">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
And a controller that launches Angular application upon successful log in:
#RequestMapping("/views/home")
public String login() {
return "index";
}
Then, in launched Angular 2 app I am planning to fetch the data by making HTTP requests, and using Springs' controllers to return me JSON. So, after Angular is launched it works by itself just interacting with the server via HTTP. After logging out a user will not get access to Angular app because it is under a protected folder and index.jsp is not in the app root folder, so it can not be launched by accessing / path.
I want to show some flash message after completion of AJAX call. I am doing like this ..
Controller Action --
def subscribe()
{
def subscribe = new Subscriber()
subscribe.email = params.subscribe
if (subscribe.save())
{
flash.message = "Thanks for your subscribtion"
}
}
View Part --
Subscribe :
<g:formRemote onSuccess="document.getElementById('subscribeField').value='';" url="[controller: 'TekEvent', action: 'subscribe']" update="confirm" name="updateForm">
<g:textField name="subscribe" placeholder="Enter your Email" id="subscribeField" />
<g:submitButton name="Submit" />
</g:formRemote >
<div id="confirm">
<g:if test="${flash.message}">
<div class="message" style="display: block">${flash.message}</div>
</g:if>
</div>
My AJAX working fine but it is not showing me flash.message. After refresh page it displaying message. How to solve it ?
When you use ajax your page content isn't re-parsed, so your code:
<g:if test="${flash.message}">
<div class="message" style="display: block">${flash.message}</div>
</g:if>
will not run again.
So I agree with #James comment, flash is not the better option to you.
If you need to update your view, go with JSON. Grails already have a converter that can be used to this:
if (subscribe.save()) {
render ([message: "Thanks for your subscribtion"] as JSON)
}
And your view:
<g:formRemote onSuccess="update(data)" url="[controller: 'TekEvent', action: 'subscribe']" name="updateForm">
<g:textField name="subscribe" placeholder="Enter your Email" id="subscribeField" />
<g:submitButton name="Submit" />
</g:formRemote >
<script type='text/javascript'>
function update(data) {
$('#subscribeField').val('');
$('#confirm').html(data.message);
}
</script>
You have couple options,
First you can try to return the message from your controller in a form of json or a map and render it on the screen your self using javascript libraries, which is a bit different if you want to use Grails ajax tags.
The other option is using a plugin like one-time-data , which
Summary A safe replacement for "flash" scope where you stash data in
the session which can only be read once, but at any point in the
future of the session provided you have the "id" required.
Description
This plugin provides a multi-window safe alternative to flash scope
that makes it possible to defer accessing the data until any future
request (so long as the session is preserved).
more
Hope it helps
I am having an issue where when a page is loaded via Ajax, I don't have a value in my search input. Here is my HTML:
<form id="searchForm" action="javascript:;" method="post">
<div>
<input type="search" name="search-mini" id="search-mini" value="" data-mini="true" />
<input type="submit" data-mini="true" value="Search" />
</div>
</form>
The reason we have an input button is because of a request from the client as they found people having scenarios where they would click "Done" on the IOS keyboard rather than "Search" which wouldn't submit the form. here is my Javascript that handles the submit:
$(document).on('submit', '#searchForm', function () {
var text = $("#search-mini").val();
text = encodeURIComponent(text);
window.location.href = "/Mobile/Browse/Text?text=" + text;
return true;
});
This all runs fine if I refresh the page so the content is not loaded via AJAX. It only fails when linking between pages and they are loaded by AJAX. Alerting out "text" has a blank value in this scenario.
I have read about using JQM initialization events such as 'PageInit' instead of DOM ready() I just need an example implementing this with my code if this is the correct approach?
Regards,
Danny
I am trying to implement something like this.
http://app.maqetta.org/mixloginstatic/LoginWindow.html
I want the login page to load but if you click the signup button then an ajax will replace the login form with the signup form.
I have got this to work using this code
dojo.xhrGet({
// The URL of the request
url: "'.$url.'",
// The success callback with result from server
load: function(newContent) {
dojo.byId("'.$contentNode.'").innerHTML = newContent;
},
// The error handler
error: function() {
// Do nothing -- keep old content there
}
});'
the only problem is the new form just loads up as a normal form, not a dojo form. I have tried to return some script with the phaser but it doesnt do anything.
<div id="loginBox"><div class="instructionBox">Please enter your details below and click <a><strong>signup</strong>
</a> to have an activation email sent to you.</div>
<form enctype="application/x-www-form-urlencoded" class="site-form login-form" action="/user/signup" method="post"><div>
<dt id="emailaddress-label"><label for="emailaddress" class="required">Email address</label></dt>
<dd>
<input 0="Errors" id="emailaddress" name="emailaddress" value="" type="text"></dd>
<dt id="password-label"><label for="password" class="required">Password</label></dt>
<dd>
<input 0="Errors" id="password" name="password" value="" type="password"></dd>
<dt id="captcha-input-label"><label for="captcha-input" class="required">Captcha Code</label></dt>
<dd id="captcha-element">
<img width="200" height="50" alt="" src="/captcha/d7849e6f0b95cad032db35e1a853c8f6.png">
<input type="hidden" name="captcha[id]" value="d7849e6f0b95cad032db35e1a853c8f6" id="captcha-id">
<input type="text" name="captcha[input]" id="captcha-input" value="">
<p class="description">Enter the characters shown into the field.</p></dd>
<dt id="submitButton-label"> </dt><dd id="submitButton-element">
<input id="submitButton" name="submitButton" value="Signup" type="submit"></dd>
<dt id="cancelButton-label"> </dt><dd id="cancelButton-element">
<button name="cancelButton" id="cancelButton" type="button">Cancel</button></dd>
</div></form>
<script type="text/javascript">
$(document).ready(function() {
var widget = dijit.byId("signup");
if (widget) {
widget.destroyRecursive(true);
}
dojo.parser.instantiate([dojo.byId("loginBox")]);
dojo.parser.parse(dojo.byId("loginBox"));
});
</script></div>
any advice on how i can get this to load as a dojo form. by the way i am using Zend_Dojo_Form, if i run the code directly then everything works find but through ajax it doesnt work. thanks.
update
I have discovered that if I load the form in my action and run the __toString() on it it works when i load the form from ajax. It must do preparation in __toString()
Firstly; You need to run the dojo parser on html, for it to accept the data-dojo-type (fka dojoType) attributes, like so:
dojo.parser.parse( dojo.byId("'.$contentNode.'") )
This will of course only instantiate dijits where the dojo type is set to something, for instance (for html5 1.7+ syntax) <form data-dojo-type="dijit.form.Form" action="index.php"> ... <button type="submit" data-dojo-type="dijit.form.Button">Send</button> ... </form>.
So you need to change the ajax contents which is set to innerHTML, so that the parser reckognizes the form of the type dijit.form.Form. That said, I urge people into using a complete set of dijit.form.* Elements as input fields.
In regards to:
$(document).ready(function() {});
This function will never get called. The document, youre adding innerHTML to, was ready perhaps a long time a go.
About Zend in this issue:
Youre most likely rendering the above output form from a Zend_ Dojo type form. If the renderer is set as programmatic, you will see above html a script containing a registry for ID=>dojoType mappings. The behavior when inserting <script> as an innerHTML attribute value, the script is not run under most circumstances (!).
You should try something similar to this pseudo for your form controller:
if request is ajax dojoHelper set layout declarative
else dojoHelper set layout programmatic