I'm trying to make a client-server application where from the client I send a request through a JSON object to the server to register. The thing is I should get another JSON with an "OK" field (which is actually being sent) but for some reason the client keeps going to the .fail function instead of the .done one (sorry if some of used terms are not very accurate, I'm new to this).
So I'll this is my code incase you can check if there's anything wrong causing this:
Client JS:
define(['ojs/ojcore', 'knockout', 'jquery', 'appController', 'jquery', 'ojs/ojknockout', 'ojs/ojinputtext'],
function(oj, ko, $, app) {
function RegistrarseViewModel() {
var self = this;
this.email = ko.observable();
this.pwd1 = ko.observable();
this.pwd2 = ko.observable();
this.registrar = function(){
alert("Se ha mandado el registro");
var p = {tipo:"Registrarse",email: this.email(), pwd1:this.pwd1(), pwd2:this.pwd2()};
$.ajax({
type:"POST",
url:"http://localhost:8080/ServidorWeb/Registrarse.jsp",
data: "p=" + JSON.stringify(p)
}).done(function(data, textStatus, jqXHR){
alert("Comprobando tipo");
if (data.tipo == "OK"){
//window.location="index.html?root=juegos"
sessionStorage.jugador=self.email();
app.router.go("login");
alert("Registro correcto");
}else
alert(respuesta.texto)
}).fail(function() {
alert("Sorry. Server unavailable. lol ");
});
}
this.cancelar = function(){
app.router.go("login");
}
}
return new RegistrarseViewModel();
}
);
Server JSP:
<%# page language="java" contentType="application/json ; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# page import= "org.json.*,dominio.Manager"%>
<%
String p = request.getParameter("p");
JSONObject resultado=new JSONObject();
try{
JSONObject jso= new JSONObject(p);
if(!jso.getString("tipo").equals("Registrarse")){
resultado.put("tipo","NOK");
resultado.put("texto","Mensaje inesperado");
}else{
String email=jso.getString("email");
String pwd1=jso.getString("pwd1");
String pwd2=jso.getString("pwd2");
Manager.get().registrarse(email,pwd1,pwd2);
resultado.put("tipo","OK");
resultado.put("texto","Te has registrado con el email " + email);
}
}
catch(Exception e){
resultado.put("tipo","NOK");
resultado.put("texto","Mensaje Inesperadoo");
}
%>
<%=resultado.toString()%>
After executing Manager.get().registrarse(email,pwd1,pwd2); (which is the logic to register into a MongoDB) it just continues with the resultado.put("tipo","OK"); line which means the problem isn't in there.
Also if I send the request http://localhost:8080/ServidorWeb/Registrarse.jsp?p=%7Btipo:%22Registrarse%22,email:%2233%22,pwd1:%2220%22,pwd2:%2220%22%7D from a browser like Google Chrome it prints this: {"texto":"Te has registrado con el email 33","tipo":"OK"} but from the real client it just won't get into the .done function, idk why.
I really hope you can help me.
Thanks in advance.
EDIT 1: Added the server response from the browser console IMAGE
Okay I solved this finally.
I had to add this line at the beggining of the .jsp, this was an issu with TomCat which has something like 2 machines and without this line it doesn't allow communication among different machines because of security reasons it seems.
response.setHeader("Access-Control-Allow-Origin", "*");
if you use jquery the correct way is use serialize function from jquery
https://api.jquery.com/serialize/
first give a id for you form something like :
`
$("#myform form").submit(function(event){
event.preventDefault();
var sendData = $("#myform form").serialize();
$.post("your-PHP-handler.php", sendData);
});
<form id="myform" method="post" action="your-PHP-handler.php">
<input type="name" placeholder="name">
<input type="name" placeholder="age">
<input type="name" placeholder="address">
<button type="submit">send</button>
</form>
`
note when you submit your form via javascript the serialization jquery get all inputs in your post end send all together you cam handler the response php inside of $.post() you can make many things with this consulting jquery documentation.
anyway the basic is there , get everything inside my form and send to my php file
Related
I have a script making a file from data (from a form or not). I have access to the URL to download the file in any browser, using window.URL.createObjectURL. But I would like to add a button to send the file by email. (I have a server and PHP).
Here is my code:
First creating File from 'test':
function makeFile(text) {
var test =
"Here is my " + text;
var data = new File([test], { type: "text/plain" });
if (myFile !== null) {
window.URL.revokeObjectURL(myFile);
}
myFile = window.URL.createObjectURL(data);
return myFile;
}
Now my unsuccessful attempt:
<form action="emailthijob.php" method="post">
<a class="download hide" id="sendbyemail" onclick="myFile.submit()";>⇧ Email</a>
</form>
So I would appreciate help with 1/button to click and send mail, 2/ PHP code to actually get the result.
Thank you very much for your help,
Best,
--Fred
I'm trying to use flask with url_for. The problem is that when I try to launch an alert with the value of the javascript variable everything seems ok, but when I try to launch a alert with the url_for the content of the variable is not printed. What I'm doing wrong? or What is missing in my code?
How can I pass a JavaScript variable into the url_for function?
html code:
<a class="dissable_user_btn" data-user_id="{{user.id}}" href="#" title="Change Status"><i class="fa fa-plug"></i>
</a>
JS Code:
<script type="text/javascript">
$(document).ready(function(){
$('.dissable_user_btn').click(function( event ) {
var user_id = $(this).data("user_id")
alert(user_id) //everything ok
alert ('{{url_for('.dissable', _id=user_id)}}'); //dont print the valur of user_id
</script>
Short answer: you can't. Flask & Jinja2 render the template on the server side (e.g. Flask is translating all of the {{ }} stuff before it sends the HTML to the web browser).
For a URL like this where you're including a variable as part of the path you'd need to build this manually in javascript. If this is an XHR endpoint I'd recommend using GET/POST to transfer the values to the server as a better best practice than constructing the URL this way. This way you can use Jinja:
$(document).ready(function(){
var baseUrl = "{{ url_for('disable') }}";
$('.dissable_user_btn').click(function(event) {
var user_id = $(this).data("user_id");
// first part = url to send data
// second part = info to send as query string (url?user=user_id)
// third parameter = function to handle response from server
$.getJSON(baseUrl, {user: user_id}, function(response) {
console.log(response);
});
});
});
I found another solution for this. My problem started when I needed to pass a variable with space.
First I created a function to remove trailing and leading spaces
function strip(str) {
return str.replace(/^\s+|\s+$/g, '');}
After that, I used the function and encoded the URL
<script type="text/javascript">
$(document).ready(function(){
$('.dissable_user_btn').click(function( event ) {
var user_id = $(this).data("user_id")
alert(user_id)
user_id = strip(user_id).replace(" ","%20");
alert ('{{url_for('.dissable', _id='user_id')}}.replace('user_id',user_id);
</script>
It worked pretty nice for me!
This is how I applied to my problem
<script>
function strip(str) {
return str.replace(/^\s+|\s+$/g, '');}
$(document).ready(function() {
$('#exportcountry').click(function() {
var elemento = document.getElementById("countryexportbtn");
var country = strip(elemento.textContent).replace(" ","%20");
$('#exportevent').load("{{ url_for('get_events',country = 'pais') }}".replace('pais',country));
});
});
</script>
I am currently dynamically loading various JSPs using an Ajax call. However, once a JSP is loaded none of the Javascript contained inside is working. I am assuming this is because the Script inside has not been parsed yet.
To that end I found the module "aui-parse-content" which, according to its description, should be able to parse the contained script.
The ParseContent Utility - Parse the content of a Node so that all of the javascript contained in that Node will be executed according to the order that it appears.
However, I can't get it to work. Here is my AUI:Script for reference.
<portlet:resourceURL var="viewContentURL">
<portlet:param name="jsp" value="<%= tmp %>"/>
</portlet:resourceURL>
<div id="<portlet:namespace />jspcontent"></div>
<aui:script use="aui-base, aui-io-request,aui-parse-content, aui-node">
var url = '<%= viewContentURL.toString() %>';
AUI().io.request(
url,
{
on:{
success: function(){
var message = this.get('responseData');
//alert(message);
AUI().one('#<portlet:namespace />jspcontent').html(message);
AUI().one('#<portlet:namespace />jspcontent').plug(AUI().Plugin.ParseContent);
},
failure: function(){
alert("An error occured");
}
}
}
);
</aui:script>
Thank you in advance!
-John
Edit:
Since I found a fix a while ago and others might have the same problem this is how I got aui-parse-content working:
on:{
success: function(){
var message = this.get('responseData');
var tmp = A.one('#<portlet:namespace />jspcontent');
tmp.html(message);
tmp.plug(A.Plugin.ParseContent);
tmp.ParseContent.parseContent(message);
},
}
I found a fix a while ago and others might have the same problem this is how I got aui-parse-content working:
on:{
success: function(){
var message = this.get('responseData');
var tmp = A.one('#<portlet:namespace />jspcontent');
tmp.html(message);
tmp.plug(A.Plugin.ParseContent);
tmp.ParseContent.parseContent(message);
},
}
I also amended my original post to reflect my findings
So allow me to first say I have looked at previous questions, and none of them have helped me out. My problem is as follows, I have an html file with a form which calls a javascript function to load a php file.
The form looks as following:
<form method="GET" id="submission" >
<div class="form-group">
<label for="q">Search Term:</label>
<input type="text" class="form-control" id="q" name="q" placeholder="enter a keyword">
</div>
<div class="form-group">
<label for="location">location</label>
<input type="text" class="form-control" id="location" name="location" placeholder="lat,long">
</div>
<div class="form-group">
<label for="locationRadius">Location Radius:</label>
<input type="text" class="form-control" id="locationRadius" name="locationRadius" placeholder="25km">
</div>
<div class="form-group">
<label for="maxResults">Max Results:</label>
<input type="number" class="form-control" id="maxResults" name="maxResults" placeholder="0 to 50">
</div>
<button type="submit" id="submitButton" >Submit</button>
</form>
The JS function responsible for sending is the following:
function sendData() {
var keyword = document.getElementById("q").value;
var location = $('#location').value;
var locationRadius = $('#locationRadius').value;
var maxResult = $('#maxResults').value;
alert("keyword is: " + locationRadius);
$.get(
{
type: 'GET',
url: '../php/geolocation.php',
data : {q: keyword, location: location, locationRadius: locationRadius, maxResults: maxResult}
},
function (data) {
//alert("Data loaded " + data);
document.getElementById("geolocation-results").innerHTML = data;
}
);
}
$(document).ready(function() {
$("#submission").submit(function() {
sendData();
return false;
});
});
SO my problem is two fold, how to call it in an ajax like manner as the above format worked for my old code, but for some reason refuses to function correctly for this one. And how should I fetch the php data? The php code is below:
It is a modified version of youtube's geolocation example code.
<?php
/**
* This sample lists videos that are associated with a particular keyword and are in the radius of
* particular geographic coordinates by:
*
* 1. Searching videos with "youtube.search.list" method and setting "type", "q", "location" and
* "locationRadius" parameters.
* 2. Retrieving location details for each video with "youtube.videos.list" method and setting
* "id" parameter to comma separated list of video IDs in search result.
*
* #author Ibrahim Ulukaya
*/
/**
* Library Requirements
*
* 1. Install composer (https://getcomposer.org)
* 2. On the command line, change to this directory (api-samples/php)
* 3. Require the google/apiclient library
* $ composer require google/apiclient:~2.0
*/
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}
require_once __DIR__ . '/vendor/autoload.php';
$htmlBody = null;
// This code executes if the user enters a search query in the form
// and submits the form. Otherwise, the page displays the form above.
if (isset($_GET['q'])
&& isset($_GET['maxResults'])
&& isset($_GET['locationRadius'])
&& isset($_GET['location'])) {
/*
* Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
$DEVELOPER_KEY = 'AIzaSyC6q-84bJv9HWCUDT4_SQ5Bp9WFJW2Z-e4';
$client = new Google_Client();
$client->setDeveloperKey($DEVELOPER_KEY);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
try {
// Call the search.list method to retrieve results matching the specified
// query term.
$searchResponse = $youtube->search->listSearch('id,snippet', array(
'type' => 'video',
'q' => $_GET['q'],
'location' => $_GET['location'],
'locationRadius' => $_GET['locationRadius'],
'maxResults' => $_GET['maxResults'],
));
$videoResults = array();
# Merge video ids
foreach ($searchResponse['items'] as $searchResult) {
array_push($videoResults, $searchResult['id']['videoId']);
}
$videoIds = join(',', $videoResults);
# Call the videos.list method to retrieve location details for each video.
$videosResponse = $youtube->videos->listVideos('snippet, recordingDetails', array(
'id' => $videoIds,
));
$videos = '';
// Display the list of matching videos.
foreach ($videosResponse['items'] as $videoResult) {
$videos .= sprintf('<li>%s,%s (%s,%s)</li>',
$videoResult['id'],
$videoResult['snippet']['title'],
$videoResult['recordingDetails']['location']['latitude'],
$videoResult['recordingDetails']['location']['longitude']);
echo $videos;
}
//$htmlBody = <<<END
// <h3>Videos</h3>
// <ul>$videos</ul>
//END;
} catch (Google_Service_Exception $e) {
$htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
}
?>
It appears that the problem is your attempt to specify an non asynchronous request. I believe these are blocked by current/modern browsers. If you check your javascript console, you will probably see an error like this:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
If you remove that, I believe it will work as before (if it worked earlier, as you indicated). jQuery ajax requests are asynchronous by default, so if you remove that line, it will operate asynchronously.
(This wasn't part of your question, but you might consider leaving your input field's value="" blank, and put your helper text in placeholder="" attributes instead. These will provide the clue to your users without the risk of having that information passed in your request.)
As for displaying the result of the call, having your call return HTML and simply displaying that HTML on your calling page should work. Since you're using jQuery you could simplify your code like so: $('#geolocation-results').html(data); You may need/want to specify dataType: 'html' in your call as well. (https://api.jquery.com/jquery.get/)
Oh my. So obvious now. I believe your structure of the .get call is wrong. Should be like this:
$.get(
"../php/geolocation.php",
{
q: keyword,
location: location,
locationRadius: r,
maxResults: maxResult
},
function (data) {
$('#geolocation-results').html(data);
}
);
Checking that now... Okay, after rushing a bit too much I can confirm that the $.get() call was just structured wrong. Correct it as shown above and it will call the PHP file correctly and display the output in the geolocation-results element.
I think there are some mistakes in your code. You don't need to put async (and not asynch) as false because it's blocking the client browser for nothing. Be also careful to your url parameter which should not contains any quotes. Finally, you should put your trigger on the submit event more than on the onclick event because you can submit the form just by pressing Enter without clicking on your button.
You can try with this javascript :
function sendData() {
var keyword = document.getElementById("q").value;
var location = $('#location').value;
var locationRadius = $('#locationRadius').value;
var maxResult = $('#maxResults').value;
alert("keyword is: " + keyword);
$.get(
'../php/geolocation.php',
{q: keyword, location: location, locationRadius: locationRadius, maxResults: maxResult},
function (data) {
alert("Data loaded " + data);
document.getElementById("geolocation-results").innerHTML = data;
}
);
}
$(document).ready(function() {
$("#submission").submit(function() {
sendData();
return false;
}
});
I have an Ajax form that I need to hit a JavaScript function on failure, like so:
using (Ajax.BeginForm("UpdateStages", new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "refreshSearchResults('" + #Model.First().ItemCode + "')",
OnFailure = "showError"
}))
With the showError function taking the Ajax context response and appending it to a div, like so:
function showError(ajaxContext)
{
var response = ajaxContext.responseText;
response = $($.trim(response));
var itemVersion = response.filter("div")[0].innerHTML.trim().toString();
var error = response.filter("p")[0].outerHTML.toString();
$("#" + itemVersion.replace(".", "") + "-UpdateStagesResults").empty();
$(error).appendTo("#" + itemVersion.replace(".", "") + "-UpdateStagesResults");
}
In order for the OnFailure to be called I have in my MVC controller ActionResult, when an error occurs:
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return PartialView();
which returns a PartialView with the error message in the ViewBag. This works fine when running locally, the error message is sent to the showError function and then the error is appended to the page.
The problem is that when I put the application onto a live server (IIS7), the Ajax context is just
Bad Request
and for example is not:
<p>You have not entered a valid date.</p>
<div style="display:none;">V7.0 </div>
Any help would be great!
I've had this,
in IIS7 the default error settings are to show detailed error messages locally only., your view is replaced with the default for the status code.
If you want to see your custom errors, add this into your web.config
<system.webServer>
<httpErrors errorMode="Detailed" />
</system.webServer>
that should sort it