jsp page being overwritten by JSON data being sent from Servlet - json

I am trying to send JSON data to my JSP page from a servlet.
AS soon as I run the JSP, the whole of JSP gets overwritten by the JSON content. why is this happening? This is part of my JSP page.
<%# page import="java.util.ArrayList" %>
<head>
<script>
function populateTypeOfWork(workType) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var work = JSON.parse(this.responseText);
workType.options.length = 0;
for (i = 0; i < work.length; i++) {
createOption(workType, workDesc[i], workDesc[i]);
}
}
xhttp.open("GET", "ServletRequest", true);
xhttp.send();
}
}
function createOption(dropdown, text, value) {
var x = document.createElement('option');
x.value = value;
x.text = text;
dropdown.options.add(x);
}
</script>
</head>
<body>
<label>Work Category **</label>
<select id="workCategory"
onchange="populateTypeOfWork(document.getElementById('workTypeDesc1'))"
size=1
style="width:95%;" required>
<option value="" selected>Select A Work Category</option>
<% ArrayList workCategory = (ArrayList)
request.getAttribute("workCategory");
for (int i = 0; i < workCategory.size(); i++) {
%>
<option value="<%=workCategory.get(i)%>"><%=workCategory.get(i)%>
</option>
<% } %>
</select> <br>
<label>Type Of Work **</label>
<select id="workTypeDesc1" size=1 style="width:95%;" required>
<option value="" selected>Type of Work</option>
</select>
</body>
</html>
Servlet
String json = new Gson().toJson(arraylistvar);
res.setContentType("application/json");
PrintWriter pw = res.getWriter();
pw.flush();
pw.close();
req.setAttribute("viewURL","/page1.jsp");
Why does stackoverflow keep asking me to add more details? because its mostly code..?? why should I fill this post unnecessaily?

There are two problems I can see with the current code: (1) you are referencing a non-existent variable workDesc; it appears you should reference the variable named work instead, and (b) the code that sends the AJAX request is inside the onreadystatechange() event handler, when it should actually execute right after the event handler is set. Here is the revised code snippet:
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var work = JSON.parse(this.responseText);
workType.options.length = 0;
for (i = 0; i < work.length; i++) {
createOption(workType, work[i], work[i]);
}
}
}
xhttp.open("GET", "ServletRequest", true);
xhttp.send();

This might be due to how the request is being made from your web page. You should be using an AJAX call; make sure you are not submitting an ordinary form or changing the URL of the page within your JavaScript.

Related

Apps script return values from server function to html form

I need help of professionals at Apps script. I have the project implemented by web-app.
I wrote script on server-part
var url = "https://docs.google.com/spreadsheets/d/1s8l-8N8dI-GGJi_mmYs2f_88VBcnzWfv3YHgk1HvIh0/edit?usp=sharing";
var sprSRCH = SpreadsheetApp.openByUrl(url);
let sheetSRCHSSCC = sprSRCH.getSheetByName("PUTAWAY_TO");
function GetQ(){
var QPLAN = sheetSRCHSSCC.getRange("M2:M").getValues().filter(String).length;
var myArray = sheetSRCHSSCC.getRange("O2:O" + (QPLAN + 1)).getValues();
var QFACT = 0;
for (i = 0; i < myArray.length; i++) {
if (myArray[i] != "") {
QFACT += 1
}
}
}
I need to return values from this function to inputs:
QFACT to FACT
QPLAN to PLAN
<div class="input-field col s3">
<input disabled value="" id="PLAN" type="text" >
<label for="disabled">PLAN</label>
</div>
<div class="input-field col s3">
<input disabled value="" id="FACT" type="text" >
<label for="disabled">FACT</label>
</div>
I will be grateful for the help. I'm new at this))
If you are using Apps Script deploying Web App, I can see 2 possibilities :
1/ Get data at the loading of the page (and only at the loading) :
In code.gs :
function doGet() {
var tmp = HtmlService.createTemplateFromFile('page');
tmp.QFACT = "hello";
tmp.PLAN = "World!";
return tmp.evaluate();
}
In page.html :
<html>
<body>
<h5><?= QFACT ?></h5>
<h5><?= QPLAN ?></h5>
</body>
</html>
2/ If you need to refresh the data by click button, or something else, you will need to operate diffently :
Add a page-js.html to your project, and bind it at the end of your page.html
<html>
<body>
<h5 id="QFACT"></h5>
<h5 id="QPLAN"></h5>
</body>
<?!= include("page-js"); ?>
</html>
then in your page-js.html :
<script>
function refresh() {
google.script.run.withSuccessHandler(callback).refresh();
}
function callback(e) {
document.getElementById('QPLAN').innerHTML = e.QPLAN;
document.getElementById('QFACT').innerHTML = e.QFACT;
}
</script>
and finally add the refresh() function in your code.gs :
function refresh() {
var obj = {};
obj.QPLAN = "QPLAN";
obj.QFACT = "QFACT";
return obj;
}

How to i pass variable value to input text value?

I would like to compare user input with predefined value on same jsp page. If the input value is same as expected, then i allow user go ahead to submit the request form. But i don't know how set the predefined value for checking. Thanks.
<tr><td>Application</td></tr>
<%
String strDBCode = "123456789";
out.println("<tr><td><b>Please input your pass code here:</b></td></tr>");
out.println("<tr><td><input type='text' name='strPassCode' value=''></td></tr>");
out.println("<tr><td><input type='hidden' name=strDBPassCode size='15' maxlength='15' value=strDBCode id='b'></td></tr>");
out.println("<tr><td><input type='button' name='chkPassCode' value=' Check ' onClick='return chkPCode()'></td></tr>");
%>
<script type="text/javascript">
function chkPCode()
{
var a = document.getElementById("a");
var b = document.getElementById("b");
var valid = true;
if (a.value != b.value) {
alert("Not Match!");
valid = false;
}
else {
alert("Match");
valid = true;
}
return valid;
}
</script>
I expect b value should be "123456789", but b always equal to "strDBPassCode". I have try set
out.println(" id='b'>");
It return error. Since the input already inside <% %>.
Apart from that, how to disable the input text box if valid return is true?
Any idea? thanks.
This is because you are not referring to the variable you declared.
out.println("<tr><td><input type='hidden' name=strDBPassCode size='15' maxlength='15' value="+strDBCode+" id='b'></td></tr>");
__________↑
Similar way, you can update the name attribute in above code.
Do not write scriptlets in JSP, because scriptlets shouldn't be used in JSPs for more than a decade. Learn the JSP EL, the JSTL, and use servlet for the Java code.
See How to avoid Java Code in JSP-Files?
<script type="text/javascript">
function chkPCode()
{
var a = document.getElementById("a");
var b = document.getElementById("b");
var valid = true;
if (a.indexOf(b) == -1) {
alert("Not similar!");
valid = false;
}
else {
alert("Input value exist!");
valid = true;
}
return valid;
}
</script>

How to get form submit object keys and iterate over them in google apps script?

I have a form that looks like this:
<form id="myForm" onsubmit="handleFormSubmit(this)">
<label for="Identity">Identity</label>
<select class="input-combobox" id="parentAttr" value="Identity" name="Identity">
<? var dropdownOptions = getDropdownOptions(); ?>
<option name="Identity" value="placeholder"></option>
<?
for(i=0; i<dropdownOptions.length;i++){
?>
<option value= "<?= dropdownOptions[i] ?> "> <?= dropdownOptions[i] ?> </option>
<? } ?>
</select>
<input name="myFile" type="file" />
<input type="submit" value="Submit" />
</form>
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
}
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Got it!';
}
</script>
and in Code.gs
function processForm(formObject) {
Logger.log(formObject); //logs {myFile=FileUpload, Identity=c } Those are the values I picked in my form.
}
After I log the formObject. I want to Log formObject.keys- im not sure what the call is as the formObject doesn't seem to be a valid javascript object. Further I would like to do something like for (var key in formObject.keys) {execute something} but Im not sure how to iterate through this formObject either.
Have you actually tried this and run into any errors? The for loop for iterating over object properties is
for(var key in object) {
Logger.log(key); // logs property name
Logger.log(object[key]); //logs value for the property
}
Another option to log property names
Logger.log(Object.keys(yourFormObject));

Angular 2 Datalist Option click event in Angular 2 [duplicate]

I'm using a <datalist>
<datalist id="items"></datalist>
And using AJAX to populate the list
function callServer (input) {
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
//return the JSON object
console.log(xmlhttp.responseText);
var arr = JSON.parse(xmlhttp.responseText);
var parentDiv = document.getElementById('items');
parentDiv.innerHTML = "";
//fill the options in the document
for(var x = 0; x < arr.length; x++) {
var option = document.createElement('option');
option.value = arr[x][0];
option.innerHTML = arr[x][1];
//add each autocomplete option to the 'list'
option.addEventListener("click", function() {
console.log("Test");
});
parentDiv.appendChild(option);
};
}
}
xmlhttp.open("GET", "incl/search.php?value="+input.value, true);
xmlhttp.send();
}
However I can't get it to perform an action when I click on a selection in the datalist, for example if I type in "Ref F" and the item "Ref flowers" comes up, if I click on it I need to execute an event.
How can I do this?
option.addEventListener("click", function() {
option.addEventListener("onclick", function() {
option.addEventListener("change", function() {
Sorry for digging up this question, but I've had a similar problem and have a solution, that should work for you, too.
function onInput() {
var val = document.getElementById("input").value;
var opts = document.getElementById('dlist').childNodes;
for (var i = 0; i < opts.length; i++) {
if (opts[i].value === val) {
// An item was selected from the list!
// yourCallbackHere()
alert(opts[i].value);
break;
}
}
}
<input type='text' oninput='onInput()' id='input' list='dlist' />
<datalist id='dlist'>
<option value='Value1'>Text1</option>
<option value='Value2'>Text2</option>
</datalist>
This solution is derived from Stephan Mullers solution. It should work with a dynamically populated datalist as well.
Unfortunaltely there is no way to tell whether the user clicked on an item from the datalist or selected it by pressing the tab-key or typed the whole string by hand.
Due to the lack of events available for <datalist> elements, there is no way to a selection from the suggestions other than watching the input's events (change, input, etc). Also see my answer here: Determine if an element was selected from HTML 5 datalist by pressing enter key
To check if a selection was picked from the list, you should compare each change to the available options. This means the event will also fire when a user enters an exact value manually, there is no way to stop this.
document.querySelector('input[list="items"]').addEventListener('input', onInput);
function onInput(e) {
var input = e.target,
val = input.value;
list = input.getAttribute('list'),
options = document.getElementById(list).childNodes;
for(var i = 0; i < options.length; i++) {
if(options[i].innerText === val) {
// An item was selected from the list!
// yourCallbackHere()
alert('item selected: ' + val);
break;
}
}
}
<input list="items" type="text" />
<datalist id="items">
<option>item 1</option>
<option>item 2</option>
</datalist>
Use keydown
Contrary to the other answers, it is possible to detect whether an option was typed or selected from the list.
Both typing and <datalist> clicks trigger the input's keydown listener, but only keyboard events have a key property. So if a keydown is triggered having no key property, you know it was a click from the list
Demo:
const opts = document.getElementById('dlist').childNodes;
const dinput = document.getElementById('dinput');
let eventSource = null;
let value = '';
dinput.addEventListener('keydown', (e) => {
eventSource = e.key ? 'input' : 'list';
});
dinput.addEventListener('input', (e) => {
value = e.target.value;
if (eventSource === 'list') {
alert('CLICKED! ' + value);
}
});
<input type="text" id="dinput" list="dlist" />
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
Notice it doesn't alert if the value being clicked is already in the box, but that's probably desirable. (This could also be added by using an extra tracking variable that will be toggled in the keydown listener.)
Datalist actually don't have an event (not all browsers), but you can detect if a datalist option is selected in this way:
<input type="text" list="datalist" />
<datalist id="datalist">
<option value="item 1" />
<option value="item 2" />
</datalist>
window.addEventListener('input', function (e) {
let event = e.inputType ? 'input' : 'option selected'
console.log(event);
}, false);
demo
Shob's answer is the only one which can detect when an option gets clicked as well as not trigger if an intermediary written text matches an option (e.g.: if someone types "Text1" to see the options "Text11", "Text12", etc. it would not trigger even if "Text1" is inside the datalist).
The original answer however did not seem to work on newer versions of Firefox as the keydown event does not trigger on clicks so I adapted it.
let keypress = false;
document.getElementById("dinput").addEventListener("keydown", (e) => {
if(e.key) {
keypress = true;
}
});
document.getElementById("dinput").addEventListener('input', (e) => {
let value = e.target.value;
if (keypress === false) {
// Clicked on option!
console.debug("Value: " + value);
}
keypress = false;
});
<input type="text" id="dinput" list="dlist" />
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
Datalist don't support click listener and OnInput is very costly, checking everytime all the list if anything change.
What I did was using:
document.querySelector('#inputName').addEventListener("focusout", onInput);
FocusOut will be triggered everytime a client click the input text and than click anywhere else. If they clicked the text, than clicked somewhere else I assume they put the value they wanted.
To check if the value is valid you do the same as the input:
function onInput(e) {
var val = document.querySelector('#inputName').value;
options = document.getElementById('datalist').childNodes;
for(var i = 0; i < options.length; i++) {
if(options[i].innerText === val) {
console.log(val);
break;
}
}
}
<input type="text" id="buscar" list="lalista"/>
<datalist id="lalista">
<option value="valor1">texto1</option>
<option value="valor2">texto2</option>
<option value="valor3">texto3</option>
</datalist>
//0 if event raised from datalist; 1 from keyboard
let idTimeFuekey = 0;
buscar.oninput = function(){
if(buscar.value && idTimeFuekey==0) {
alert('Chévere! vino desde la lista')
}
};
buscar.onkeydown = function(event){
if(event.key){ //<-- for modern & non IE browser, more direct solution
window.clearInterval(idTimeFuekey);
idTimeFuekey = window.setInterval(function(){ //onkeydown --> idTimeFuekey++ (non 0)
window.clearInterval(idTimeFuekey);
idTimeFuekey = 0 //after 500ms onkeydown --> 0 (could work 500, 50, .. 1)
}, 500)
}
}
Well, at least in Firefox the onselect event works on the input tag
<input type="text" id="dinput" list="dlist" onselect="alert(this.value)"/>
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
After having this problem and not finding a suitable solution, I gave it a shot.
What I did was look at the "inputType" of the given input event on top of the event toggle variable from above, like so:
eventSource = false;
const selector = document.getElementById("yourElementID");
selector.addEventListener('input', function(evt) {
if(!eventSource) {
if(evt.inputType === "insertReplacementText") {
console.log(selector.value);
}
}
});
selector.addEventListener('keydown', function(evt) {
eventSource = !evt.key;
});
This works if you want to allow the user to search a field but only hit a specific function/event on selection from the datalist itself. Hope it helps!
Edit: Forgot to mention this was done through Firefox and has not been tested on other browsers.

Knockout cross class data binding

Goal: Give the user the ability to adjust mapping results.
I am running into an issue where I need to actually change the instance used of a data bound element. Disclaimer: My json data structure may be off and I am open to possible modifications. I am coding a table header mapping app so a user can verify that the headings mapped by the server are correct. The user will have the ability to map the headers if there is an issue. I have not been able to figure out how to actually update the data bound to the result when the select menu is changed. It feels like it should be super easy. I keep finding myself with basically a finished knockout app less the last step...
Markup Snippet:
<div id="wrapper" data-bind="foreach: headings">
<h1>Bind from this</h1>
<select data-bind="value: selectMenuIdVal, event: { change: updateListing }">
<option> </option>
<!-- ko foreach: $root.headings -->
<option data-bind="value: $data.CC_FIELD_ID, visible: $data.VENDOR_FIELD_NAME(), text: $data.VENDOR_FIELD_NAME"></option>
<!-- /ko -->
</select>
<h1>To this</h1>
<ul data-bind="foreach: listingFields">
<li data-bind="text: $data.VALUE"></li>
</ul>
</div>
KO Snippet:
var Heading = function(data) {
var self = this;
var heading = ko.mapping.fromJS(data, {}, this);
heading.selectMenuIdVal = ko.observable(heading.CC_FIELD_ID());
// heading.listingFields gets mapped by the mapping plugin
this.updateListing = function(ko_evt, js_evt) {
//TODO
// Get the listing results from the value of the select menu
// self.listingFields(those listings);
}
return heading;
}
Here is my fiddle: http://jsfiddle.net/breck421/SLT9B/1/
I really not sure if undertood you right.
Please let me know if this is what you are looking for :
this.updateListing = function (ko_evt, js_evt) {
console.log("fired");
//Do something freaking awesome!!!!!!!
if (vm.dataRepo) {
for (var i = 0; i < vm.dataRepo.HEADINGS.length; i++) {
if (vm.dataRepo.HEADINGS[i].CC_FIELD_ID == heading.selectMenuIdVal()) {
var listingFields = [];
for (var j = 0; j < vm.dataRepo.LISTINGS.length; j++) {
var listing = vm.dataRepo.LISTINGS[j];
var field = listing[i];
if (field) {
listingFields.push(field);
}
}
heading.listingFields(listingFields);
// heading.listingFields = listingFields;
}
}
}
}
See fiddle
I hope it helps.