Reload search results on new search in web application (without jQuery) - javascript

I have a simple web app that uses an API to return search results from a database and uses ajax to insert them into an empty ul element on the page. (Using JSONP with a cross domain request)
I cant figure out how to do it using javascript, everywhere I've found uses jQuery. I want to be able to have them enter another search term and have it clear the existing content from the page.
Currently if you conduct a second search it just appends the new results to the bottom of the existing list.

Once you have the content (returned from your API call using AJAX) you just can assign it to your ul or div e.g. document.getElementById('YourULID').innerHTML = "The content you got from your AJAX call"

From vanilla.js (so you can compare with jQuery):
var r = new XMLHttpRequest();
r.open("POST", "path/to/api", true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
alert("Success: " + r.responseText);
};
r.send("banana=yellow");

if i understand what you want. You want to get result from server and insert them into a ul form field of your webpage.
This is just an example and might help
function createRequest(){
try{
request = new XMLHttpRequest();
}catch (tryMS){
try{
request = new ActivXObject("Msxml2.XMLHTTP");
}catch (otherMS){
try{
request = new ActivXObject("Microsoft.XMLHTTP");
}catch (failed){
request = null;
}
}
}
return request;
}
function loggin(user_id,password){
request = createRequest();
data = new FormData();
data.append('user_id',user_id.value);
data.append('password',password.value);
request.onreadystatechange=function(){
if(request == null){
alert('Unable to connect');
}else{
if(request.readyState==4){
if(request.status==200){
if(request.responseText){
document.location.href = request.responseText;
}
}
}
}
}
This will create and HTTP request. Post data to your server then fetch the result and throw it back to your javascript, then staight to your webpage. Use request.responseText to append/insert to the appropriate field

I figured it out by using a few simple lines of html when onsubmit occurs with the search field:
var div = document.getElementById('cart_item');
while(div.firstChild){
div.removeChild(div.firstChild);
}

Related

Tableau REST API: Using Javascript to get the Token

I am a complete beginner with REST API and I could not figure out how I am to proceed.
I installed Postman and was successfully able to get the Token, but I am not sure how to send the raw XML payload in javascript.
<tsRequest>
<credentials name ="XXX" password="YYY" >
<site contenturl = "" />
</credentials>
</tsRequest>
I have :
httpRequest.open('POST', 'http://MY-SERVER/api/2.4/auth/signin', false);
httpRequest.setRequestHeader("Content-type", "application/xml");
Not sure how to add the xml payload. I have access to a Tableau Server(MY-SERVER) and everything.
Any help would be greatly appreciated!
Thank you!
You are getting closer, you just need to use the send method to send your XML: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
Just make sure that your XML is properly encoded in javascript when you're inputting it. So if you are using double quotes inside your XML, make sure you have single quotes to declare your string in javascript (e.g.) var data = '<credentials name="XXX" >';
Related: Send POST data using XMLHttpRequest
In addition to #AnilRedshift answer, here's the functioning code:
login_details=[];
function getToken() {
var url = "http://yourServerAddress/api/2.0/auth/signin";
var params = "<tsRequest><credentials name='Username' password='UserPassword' ><site contentUrl='' /></credentials></tsRequest>";
return zuo = new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.withCredentials = true;
xhr.onload= function(){
if (this.status === 200) {
var parsed_xml = JSON.parse(JSON.stringify(x2js.xml_str2json(xhr.responseText)))
login_details.push(parsed_xml.tsResponse.credentials._token); login_details.push(parsed_xml.tsResponse.credentials.site._id);
resolve(login_details);
}
}
xhr.onerror=reject;
xhr.send();
})
}
function getWorkbooks(){
var url = "http://serveraddress//api/2.3/sites/"+login_details[1]+"/workbooks?pageSize=1000";
return zuo = new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("X-Tableau-Auth",login_details[0]);
xhr.onload= function(){
if (this.status === 200) {
var workbooks = JSON.parse(JSON.stringify(x2js.xml_str2json(xhr.responseText)))
for (var f=0;f<workbooks.tsResponse.workbooks.workbook.length;f++){
if(workbooks.tsResponse.workbooks.workbook[f].project._name=="Default"){
workbooks_list.push(workbooks.tsResponse.workbooks.workbook[f]._id)
}
resolve();
}
}
}
xhr.onerror= function(){
console.log(xhr.responseText);
}
xhr.send();
})
}
Invoke the code with:
getToken()
.then(function(login_details){
console.log(login_details[0]+"/"+login_details[1]);
})
.then(function(){
getWorkbooks();
})
getToken() function gets the login token which has to be used in all subsequent calls.
getWorkbooks() fetches all dashboards in 'Default' project but this kind of request can be used for all GET type requests.
Please note that this approach uses hardcoded values for password and username which is generally not the best practice. It would be way better to use server side scripting or encrypting (better but still with flavs).
You can find whole step by step tutorial and running code here:
http://meowbi.com/2017/10/23/tableau-fields-definition-undocumented-api/

How do i correctly format parameters passed server-side using javascript?

I cannot figure out how to get the following code working in my little demo ASP.NET application, and am hoping someone here can help.
Here is the javascript:
function checkUserName() {
var request = createRequest();
if (request == null) {
alert("Unable to create request.");
} else {
var theName = document.getElementById("username").value;
var userName = escape(theName);
var url = "Default.aspx/CheckName";
request.onreadystatechange = createStateChangeCallback(request);
request.open("GET", url, true);
request.setRequestHeader("Content-Type", "application/json");
//none of my attempts to set the 'values' parameter work
var values = //JSON.stringify({userName:"userName"}); //"{userName:'temp name'}"; //JSON.stringify({ "userName":userName });
request.send(values);
}
}
Here is the method in my *.aspx.cs class:
[WebMethod]
[ScriptMethod(UseHttpGet=true)]
public static string CheckName(string userName)
{
string s = "userName";
return s + " modified backstage";
}
When this code runs I receive this exception:
---------------------------
Message from webpage
---------------------------
{"Message":"Invalid web service call, missing value for parameter: \u0027userName\u0027.","StackTrace":" at System.Web.Script.Services.WebServiceMethodData.CallMethod(Object target, IDictionary`2 parameters)\r\n at System.Web.Script.Services.WebServiceMethodData.CallMethodFromRawParams(Object target, IDictionary`2 parameters)\r\n at System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary`2 rawParams)\r\n at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.InvalidOperationException"}
---------------------------
OK
---------------------------
I started searching here, then went on to several threads on SO, trying quite a few combinations of quotation marks and key-value pairs, but nothing I've tried has worked.
When I remove the parameter from the C# method and request.send(), I get a response in my JS callback that I can work with. But as soon as I try to do something with parameters, I get the above exception. I'd like to know how to do this without using jQuery, if possible.
Thanks in advance.
FINAL VERSION
Using Alexei's advice, I ended up with the following, which works. The URL was missing the apostrophes on either end of the parameter value; this was keeping the call from going through.
function checkUserName() {
var request = createRequest();
if (request == null) {
alert("Unable to create request.");
} else {
var theName = document.getElementById("username").value;
var userName = encodeURIComponent(theName);
var url = "Default.aspx/CheckName?name='" + theName + "'";
request.onreadystatechange = createStateChangeCallback(request);
request.open("GET", url, true);
request.setRequestHeader("Content-Type", "application/json");
request.send();
}
}
request.send(values);
This won't work with a "GET". Try
request.open("POST", url, true);
http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp
You need to:
decide whether you want GET or POST. For GET request you need all parameters to be in Url (and body to be empty), for POST you can use both. As of current code you are expecting GET, but sending POST.
properly add query parameter - name and encoded value. encodeUriComponent is JavaScript function of choice, see Build URL from Form Fields with Javascript or jquery for details
if using POST you need to properly encode parameters there too as well specify correct "content-type" header.
if sending JSON you need to decode JSON server side.
Alternatively you can use hidden form to perform POST/GET as covered in JavaScript post request like a form submit
Side note: jQuery.ajax does most of that for you and good source to look through if you want to do all yourself.
Like Alan said, use the POST method. Or pass your arguments in your URL before opening it, e.g.
var url = "Default.aspx/CheckName?userName=" + values;
EDIT : no, it's probably a bad idea since you want to send JSON, forget what I said.
If you need to go for POST, then you need to send it like this.
var values = JSON.stringify({"'userName':'"+ userName+ "'"});
And you have to change HttpGet to HttpPost
Given that your server side method asks for GET, you need:
request.open("GET", url + "?username=" + userName, true);
request.send();
The works for me:
function checkUserName() {
var request = new XMLHttpRequest();
if (request == null) {
alert("Unable to create request.");
} else {
var userName = "Shaun Luttin";
var url = '#Url.RouteUrl(new{ action="CheckName", controller="Home"})';
request.onreadystatechange = function() {
if (request.readyState == XMLHttpRequest.DONE ) {
if(request.status == 200){
document.getElementById("myDiv").innerHTML = request.responseText;
}
else if(request.status == 400) {
alert('There was an error 400')
}
else {
alert('something else other than 200 was returned')
}
}
}
request.open("GET", url + "?username=" + userName, true);
request.send();
}
}
With this on the server side:
[HttpGet]
public string CheckName(string userName)
{
return userName + " modified backstage";
}

Ajax: how to return XML data rather than response text

As you will notice with my code below I'm returning data using responseText. I want to return it as XML data:
//Request is a flickr URL with user entered search terms:
function sendRequest (request) {
x = new XMLHttpRequest();
x.open("GET", request,true);
x.onreadystatechange = function () {
if (x.readyState==4 && x.status==200){
//The data is returned as text and added to the page:
document.getElementById("resultsContainer").innerHTML="success: Raw JSON data below <br> <br>"+x.responseText;
document.getElementById("getIms").value = "Find Images";
document.getElementById("getIms").style.background="white";
} else if (x.status == 404){
document.getElementById("resultsContainer").innerHTML="Not Found";
}
}
x.send();
}
The value that is returned and displayed on the page is something like:
jsonFlickrApi({"photos":{"page":1,"pages":476982,"perpage":1,"total":"476982","photo":[{"id":"14021160561","owner":"91285504#N05","secret":"dd4f545e17","server":"2920","farm":3,"title":"barack-obama-painting","ispublic":1,"isfriend":0,"isfamily":0}]},"stat":"ok"})
I need to be able to use this to extract the photo info to construct an image URL to be displayed on screen. But to my understanding I would need to return the value using responseXML rather than responseText.
I have tried responseXML but it gives me back null.

AJAX and Javascript not working

NO JQUERY. I am using peoplecode which is similar to JSP, ASP, and ZXZ. The ajax request is triggered am I am trying to pull the text 'Hello World' from this script...
Function IScript_AJAX_Test()
%Response.Write("<div id='hello'>Hello World</div>");
End-Function;
My javascript function that makes the ajax call looks like this...
function AJAX_test (ajax_link) {
if (typeof XMLHttpRequest == 'undefined') {
XMLHttpRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
throw new Error('This browser does not support XMLHttpRequest or XMLHTTP.');
};
}
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
document.getElementById('ajax').innerHTML = request.responseText.document.getElementById('hello').innerHTML;
//document.getElementById('ajax').innerHTML = 'Testing';
}
}
request.open('GET', ajax_link, true);
request.send();
//document.getElementById('ajax').innerHTML = ajax_link;
}
As you can see in this line..
document.getElementById('ajax').innerHTML = request.responseText.document.getElementById('hello').innerHTML;
...I am trying to grab the text by getting the innerHTML from the id. This isn't working though. When I click the button nothing happens.
I tried using the line below, but it returns an entire new page where the id would be (probably because of Peoplesoft)...
document.getElementById('ajax').innerHTML = request.responseText;
Can someone help me achieve this...
I tried your code and it works for me, with
Function IScript_AJAX_Test()
%Response.Write("<div id='hello'>Hello World");
End-Function;
and in the javascript
document.getElementById('ajax').innerHTML = request.responseText;
Make sure you call the content servlet (psc), not the portal servlet (psp), e.g.
'http://peoplesofturl/psc/ps/EMPLOYEE/HRMS/s/WEBLIB_Z_SYS.FUNCLIB.FieldFormula.IScript_AJAX_Test', otherwise you'll get the response wrapped in the peoplesoft portal.
You can generate the url from peoplecode with the GenerateScriptContentRelURL or GenerateScriptContentURL functions.
Make it simple:
Function IScript_AJAX_Test()
%Response.Write("Hello World");
End-Function;
Javascript:
document.getElementById('ajax').innerHTML = request.responseText;
Ajax might be two types. One is server-side and the other one is client-side. You are trying to get data from client side. In this case ajax fetch nothing but the whole page result of a page not a portion. You will have the whole page result(HTML output) if you write
document.getElementById('ajax').innerHTML = request.responseText;
But you cannot fetch just only the innerHtml part of certain portion of another page. On that case you will get the whole page.

How do I force or add the content length for ajax type POST requests in Firefox?

I'm trying to POST a http request using ajax, but getting a response from the apache server using modsec_audit that: "POST request must have a Content-Length header." I do not want to disable this in modsec_audit.
This occurs only in firefox, and not IE. Further, I switched to using a POST rather than a GET to keep IE from caching my results.
This is a simplified version of the code I'm using for the request, I'm not using any javascript framework.
function getMyStuff(){
var SearchString = '';
/* build search string */
...
/* now do request */
var xhr = createXMLHttpRequest();
var RequestString = 'someserverscript.cfm' + SearchString;
xhr.open("POST", RequestString, true);
xhr.onreadystatechange = function(){
processResponse(xhr);
}
xhr.send(null);
}
function processResponse(xhr){
var serverResponse = xhr.responseText;
var container = document.getElementById('myResultsContainer');
if (xhr.readyState == 4){
container.innerHTML = serverResponse;
}
}
function createXMLHttpRequest(){
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
try { return new XMLHttpRequest(); } catch(e) {}
return null;
}
How do I force or add the content length for ajax type POST requests in Firefox?
xhr.setRequestHeader("Content-Length", "0");
would be my best guess.
BTW, if you want to stop caching in IE, just add a random number onto the end, as in:
var RequestString = 'someserverscript.cfm' + SearchString + '&random=' + Math.random();
Try to actually send something instead of null (xhr.send(null);).

Categories

Resources