I have a Javascript function that is meant to end with passing an array back into my c# code
I have got it to reach the c# code, but it never passes a parameter
My Javascript is as follows
var errorsubmits = [];
var filelists = [];
var nameselect = document.getElementById("username");
var nameselected = nameselect.options[nameselect.selectedIndex].text;
if (nameselected.includes("User"))
errorsubmits.push("User Name");
var prioritylevel = document.getElementById("priority");
var priorityselected = prioritylevel.options[prioritylevel.selectedIndex].text;
if (priorityselected.includes("Priority"))
errorsubmits.push("Priority");
var table = document.getElementById("FileTable");
var counter = 0;
var filename = "";
var images = "";
var envs = "";
var printmethod = "";
var encmethod = "";
var colour = "";
var commentsforprint = "";
var commentsforenclose = "";
for (var i = 1, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
if (counter == 0) {
if (j == 0)
filename = table.rows[i].cells[j].children[0].value;
if (j == 1)
images = table.rows[i].cells[j].children[0].value;
if (j == 2)
envs = table.rows[i].cells[j].children[0].value;
if (j == 3)
printmethod = table.rows[i].cells[j].children[0].value;
if (j == 4)
encmethod = table.rows[i].cells[j].children[0].value;
if (j == 5)
colour = table.rows[i].cells[j].children[0].value;
}
else {
if (j == 1) {
if (table.rows[i].cells[j - 1].innerHTML.includes("Print"))
commentsforprint = table.rows[i].cells[j].children[0].value;
else
commentsforenclose = table.rows[i].cells[j].children[0].value;
}
}
}
if (i % 3 == 0) {
if (filename == "")
errorsubmits.push("Filename (row:" + i + ")");
if (images == "")
errorsubmits.push("Images (row:" + i + ")");
if (envs == "")
errorsubmits.push("Envs (row:" + i + ")");
if (printmethod.includes("Method"))
errorsubmits.push("Print Method (row:" + i + ")");
if (encmethod.includes("Method"))
errorsubmits.push("Enc Method (row:" + i + ")");
if (colour.includes("?"))
errorsubmits.push("Colour (row:" + i + ")");
// alert(filename + "\n" + images + "\n" + envs + "\n" + printmethod + "\n" + encmethod + "\n" + colour + "\n" + commentsforprint + "\n" + commentsforenclose);
filelists.push(nameselected + "\t" + priorityselected + "\t" + document.getElementById('Email').textContent + "\t" + filename + "\t" + images + "\t" + envs + "\t" + printmethod + "\t" + encmethod + "\t" + colour + "\t" + commentsforprint + "\t" + commentsforenclose)
filename = "";
images = "";
envs = "";
printmethod = "";
encmethod = "";
colour = "";
commentsforprint = "";
commentsforenclose = "";
counter = 0;
}
else {
counter++;
}
}
if (errorsubmits.length != 0) {
alert("Cannot submit!\nThe following lines need filling:\n" + errorsubmits.join("\n"));
}
else {
$.ajax({
url: '?handler=Test',
contentType: 'application/json',
data: JSON.stringify(filelists)
});
}
My C# code which is currently functionless as i cant get the data is this
public JsonResult OnGetTest(IEnumerable<object>x)
{
return new JsonResult("TEST");
}
I have done an alert(JSON.stringify(filelists)) so i know that this works
(If possible i'd like to pass the raw array rather than stringifying it but i was following another SO suggestion)
The url '?handler=Test' send request like https://localhost:44389/?handler=Test&filelists=%5B%22nameselected%22%2C%22nameselected1%22%5D, because it's a HttpGet request not a POST.
Edit as per comment
1 - Function JS :
Push any string in the array filelists, and change your data to { "filelists": JSON.stringify(filelists) }
var filelists = [];
// push strings here
$.ajax({
url: '?handler=Test',
contentType: 'application/json',
data: { "filelists": JSON.stringify(filelists) }
});
2 - In the server side
public JsonResult OnGetTest(string filelists)
{
IEnumerable<string> files = JsonConvert.DeserializeObject<IEnumerable<string>>(filelists);
return new JsonResult("TEST");
}
Note that, if you need to send javascript objects in the array, you should create classes for deserializing data.
refreshFileList = function() {
$("#filedetails tr").remove();
for (i = 0, j = fileDetails.length; i < j; ++i) {
$("#filedetails").append("<tr data-filesize='" + fileDetails[i].SIZE + "' data-filename='" + fileDetails[i].KEY + "'><td><strong>" + fileDetails[i].FILENAME + "</strong></td><td class='nodesize'>" + fileDetails[i].SIZE + " MB</td><td>" + fileDetails[i].EXT + "</td>" + fileDetails[i].TAG + "</tr>");
}
},
fileDelete = function(e) {
e.preventDefault();
var parentRow = jQuery(this).closest('tr')
, fileName = fileDetails[i].KEY
, fileSize = fileDetails[i].SIZE;
ajaxFileDelete(fileName, parentRow, fileSize);
},
Into the fileDelete function I don't want to use data-filename and data-filesize but when I am going to use fileName = fileDetails[i].KEY or fileSize = fileDetails[i].SIZE its always deleting the first value of the array instead of specific value but with data-attributes it working as expected.
Add i to the <tr> as a data attribute.
refreshFileList = function() {
$("#filedetails tr").remove();
for (var i = 0, j = fileDetails.length; i < j; ++i) {
$("#filedetails").append("<tr data-index='" + i + "'><td><strong>" + fileDetails[i].FILENAME + "</strong></td><td class='nodesize'>" + fileDetails[i].SIZE + " MB</td><td>" + fileDetails[i].EXT + "</td>" + fileDetails[i].TAG + "</tr>");
}
},
fileDelete = function(e) {
e.preventDefault();
var parentRow = jQuery(this).closest('tr')
, i = parentRow.data('index')
, fileName = fileDetails[i].KEY
, fileSize = fileDetails[i].SIZE;
ajaxFileDelete(fileName, parentRow, fileSize);
},
I'm using AngularJS to prefetch images in cache client and then I want to animate those prefetched images.
My code for the prefetching:
$scope.prefetch=function(limit) {
for (var i=0; i<limit; i++) {
var date = new Date($scope.dt);
if ($scope.fileFlag == false) {
if ($scope.viewmodel.timeResolution == 'yearly')
date = new Date(date.setFullYear(date.getFullYear() + i));
else if ($scope.viewmodel.timeResolution == 'monthly')
date = new Date(date.setMonth(date.getMonth() + i));
else if ($scope.viewmodel.timeResolution == 'daily') {
date = new Date(date.setDate(date.getDate() + i));
}
} else {
date = $scope.files[$scope.files.indexOf($scope.idSelectedVote) + i];
}
console.log( $http.get(site_url + "mwf/" + $scope.viewmodel.dataSet + "/" + $scope.viewmodel.varName + "/" + $scope.viewmodel.region + "/" + date + "/map/?vMin=" + $scope.VMin + "&vMax=" + $scope.VMax + "&type=" + $scope.viewmodel.type + "&cmap=" + $scope.viewmodel.colorMap, {'cache': true}));
}
};
then i do something like this to play those images
$scope.play=function(limit) {
for (var i=0; i<limit; i++) {
$scope.map.src= site_url + "mwf/" + $scope.viewmodel.dataSet + "/" + $scope.viewmodel.varName + "/" + $scope.viewmodel.region + "/" + parseInt(date)+i + "/map/?vMin=" + $scope.VMin + "&vMax=" + $scope.VMax + "&type=" + $scope.viewmodel.type + "&cmap=" + $scope.viewmodel.colorMap;
$scope.sleepFor(500);
}
};
$scope.sleepFor = function( sleepDuration ) {
var now = new Date().getTime();
while(new Date().getTime() < now + sleepDuration){ /* do nothing */ }
}
My problem is when I call play(4) it displays only the first and the last images and not an animation. Any idea on how can I improve this code or a different approach so I can do this?
Your sleepFor is an idle loop: you spin and do nothing, but you prevent any other work from being done. This is not the way in Javascript to delay work for a set period of time, or schedule a function to be run at a later time. In Javascript we use window.setTimeout -- and in Angular we have the convenient $timeout service to provide that:
$scope.play = function(limit) {
for (var i=0; i < limit; i++) {
$scope.map.src = site_url + "mwf/" + $scope.viewmodel.dataSet + "/" + $scope.viewmodel.varName + "/" + $scope.viewmodel.region + "/" + parseInt(date)+i + "/map/?vMin=" + $scope.VMin + "&vMax=" + $scope.VMax + "&type=" + $scope.viewmodel.type + "&cmap=" + $scope.viewmodel.colorMap;
var nextFrameMs = 500;
$timeout($scope.play, nextFrameMs);
}
};
In your example, wherever your $scope is provided to you -- assuming this is in a controller, you will have some line like module.controller($scope, ...) -- you will have to inject the $timeout service to be able to use it.
Additional resources:
Angular's documentation on $timeout
MDN documentation of window.setTimeout
You have to use intervals otherwise your code will block the execution of other code
Using Angular's built in $interval service is the solution:
var playInterval;
$scope.play = function(limit) {
var interval = 1000 / 20; //20 frames per second
var i = 0;
$interval.cancel(playInterval); //stop previous animations if any
if(i < limit) {
$scope.map.src = getSrc(i++);
var cache = $interval(function() {
if(i >= limit) {
return $interval.cancel(playInterval); //or you can replace with `i = 0;` to loop the animation
}
$scope.map.src = getSrc(i++);
}, interval);
}
};
function getSrc(i) {
return site_url + "mwf/" + $scope.viewmodel.dataSet + "/" + $scope.viewmodel.varName + "/" + $scope.viewmodel.region + "/" + parseInt(date)+i + "/map/?vMin=" + $scope.VMin + "&vMax=" + $scope.VMax + "&type=" + $scope.viewmodel.type + "&cmap=" + $scope.viewmodel.colorMap;
}
I have two functions in JavaScript and get the following error:
Uncaught SyntaxError: missing ) after argument list
It is not giving me a line number and I can't seem to find the culprit; would appreciate any assistance:
function makeRequest() {
var xmlhttp = new XMLHttpRequest();
console.log('reached');
xmlhttp.onreadystatechange = function() //This part is actually executed last
{
console.log("within");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) // Was the request processed successfully?
{
console.log(location);
console.log(xmlhttp.responseText);
first = xmlhttp.responseText.substring(xmlhttp.responseText
.search('first:') + 6, xmlhttp.responseText
.search(',last'));
console.log("First: " + first);
last = xmlhttp.responseText.substring(xmlhttp.responseText
.search(',last') + 6, xmlhttp.responseText
.search(',utt'));
console.log("last: " + last);
utt = xmlhttp.responseText.substring(xmlhttp.responseText
.search(',utt') + 5, xmlhttp.responseText
.search(',type'));
console.log("utt: " + utt);
type = "";
attribute = "";
out = "";
index = "";
values = "";
if (xmlhttp.responseText.search(',att') > -1) {
type = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',type') + 6,
xmlhttp.responseText.search(',att'));
//attribute
pass = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',att') + 5,
xmlhttp.responseText.search(',vals'));
values = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',vals') + 7,
xmlhttp.responseText.search(']}'));
} else {
type = 'instance';
//index
pass = xmlhttp.responseText
.substring(xmlhttp.responseText
.search('indexResult:') + 12,
xmlhttp.responseText.search(',inst:'));
out = xmlhttp.responseText.substring(
xmlhttp.responseText.search('inst:') + 5,
xmlhttp.responseText.search('}'));
}
console.log("type: " + type);
if (type === 'attribute') {
vals = values.split(",");
html = "You have said the following to the virtual assistant: </br><i>'"
+ utt
+ "'</i></br></br>Given that you have said this; what would be your preferred "
+ attribute.toLowerCase().substring(0,
attribute.length - 1)
+ "?</br></br><select id='choice' name='attribute'><option selected='selected' value='makeSelection'>please choose</option>";
for (i = 0; i < vals.length; i++) {
html = html + "<option value='"+vals[i]+"'>"
+ vals[i] + "</option>";
}
html = html
+ "</select></br></br><input type='button' onclick='return sendChoice("
+ first + "," + last + "," + utt + "," + type
+ "," + pass + ")' value='Submit'></input>";
document.getElementById("utteranceDiv").innerHTML = html;
}
if (type === 'instance') {
html = "You have said the following to the virtual assistant: </br><i>'"
+ utt
+ "'</i></br></br>Given that you have said this; </br> "
+ out
+ "</br><select id='choice' name='attribute'><option selected='selected' value='makeSelection'>please choose</option><option value='yes'>yes</option><option value='no'>no</option></select></br></br><input type='button' onclick='return sendChoice("
+ first
+ ","
+ last
+ ","
+ utt
+ ","
+ type
+ "," + pass + ")' value='Submit'></input>";
document.getElementById("utteranceDiv").innerHTML = html;
}
}
}
console
.log("http://"
+ server
+ "/DialogueRefinementWebExperiment/WebExperimentServlet?first="
+ first + "&last=" + last);
xmlhttp
.open(
"Get",
"http://"
+ server
+ "/DialogueRefinementWebExperiment/WebExperimentServlet?first="
+ first + "&last=" + last, true);
console.log('before');
xmlhttp.send();
console.log('after');
}
and the other function is:
function sendChoice(fname, lname, utterance, type, pass) {
if (document.getElementById('choice').value === 'makeSelection') {
alert('please make a choice');
return false;
}
else {
choice = document.getElementById('choice').value;
first = fname;
last = lname;
utt = utterance;
typ = type;
attOrInstIndex = pass;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() //This part is actually executed last
{
console.log("within");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) // Was the request processed successfully?
{
console.log(location);
console.log(xmlhttp.responseText);
type = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',type') + 6,
xmlhttp.responseText.search(',att'));
attribute = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',att') + 5,
xmlhttp.responseText.search(',vals'));
values = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',vals') + 7,
xmlhttp.responseText.search(']}'));
vals = values.split(",");
console.log("type: " + type);
if (xmlhttp.responseText.search(',att') > -1) {
type = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',type') + 6,
xmlhttp.responseText.search(',att'));
//attribute
pass = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',att') + 5,
xmlhttp.responseText.search(',vals'));
values = xmlhttp.responseText.substring(
xmlhttp.responseText.search(',vals') + 7,
xmlhttp.responseText.search(']}'));
} else if (xmlhttp.responseText.search('instance') > -1) {
type = 'instance';
//index
pass = xmlhttp.responseText
.substring(xmlhttp.responseText
.search('indexResult:') + 12,
xmlhttp.responseText
.search(',inst:'));
out = xmlhttp.responseText.substring(
xmlhttp.responseText.search('inst:') + 5,
xmlhttp.responseText.search('}'));
} else {
type = 'done';
}
if (type === 'attribute') {
vals = values.split(",");
html = "You have said the following to the virtual assistant: </br><i>'"
+ utt
+ "'</i></br></br>Given that you have said this and the choices you have made so far; what would be your preferred "
+ attribute.toLowerCase().substring(0,
attribute.length - 1)
+ "?</br></br><select id='choice' name='attribute'><option selected='selected' value='makeSelection'>please choose</option>";
for (i = 0; i < vals.length; i++) {
html = html + "<option value='"+vals[i]+"'>"
+ vals[i] + "</option>";
}
html = html
+ "</select></br></br><input type='button' onclick='return sendChoice("
+ first + "," + last + "," + utt + ","
+ type + "," + pass
+ ")' value='Submit'></input>";
document.getElementById("utteranceDiv").innerHTML = html;
}
if (type === 'instance') {
html = "You have said the following to the virtual assistant: </br><i>'"
+ utt
+ "'</i></br></br>Given that you have said this and the choices you have made so far; </br> "
+ out
+ "</br><select id='choice' name='attribute'><option selected='selected' value='makeSelection'>please choose</option><option value='yes'>yes</option><option value='no'>no</option></select></br></br><input type='button' onclick='return sendChoice("
+ first
+ ","
+ last
+ ","
+ utt
+ ","
+ type
+ ","
+ pass
+ ")' value='Submit'></input>";
document.getElementById("utteranceDiv").innerHTML = html;
} else {
//done make final Page.
html = "Thank you this scenario is over.";
document.getElementById("utteranceDiv").innerHTML = html;
}
}
}
xmlhttp
.open(
"Post",
"http://"
+ server
+ "/DialogueRefinementWebExperiment/WebExperimentServlet",
true);
//xmlhttp.setRequestHeader("accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
console.log('before');
if (typ == "attribute") {
xmlhttp.send("first=" + first + "&last=" + last
+ "&mainType=" + type + "&att=" + attOrInstIndex
+ "&utt=" + utt + "&choice=" + choice + "&done=no");
} else if (typ == "instance") {
xmlhttp.send("first=" + first + "&last=" + last
+ "&mainType=" + type + "&indexResult="
+ attOrInstIndex + "&utt=" + utt + "&choice="
+ choice + "&done=" + choice);
}
}
}
The HTML is:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<script>
window.onload = function init() {
server = window.location.host;
params = location.search.split("?")[1];
first = params.split("&")[0].split("=")[1];
last = params.split("&")[1].split("=")[1];
}
</script>
</head>
<body>
<div id="utteranceDiv">
When you are ready click Submit and the system will begin to ask you
questions in an attempt to find you a restaurant that you are happy
with.</br> <input type="button" onclick="return makeRequest()"
value="Select"></input>
</div>
<script type="text/javascript">
//see above for javascipt
</script>
</body>
</html>
the div gets updated after the first call:
<div id="utteranceDiv">
You have said the following to the virtual assistant: <br><i>'i want a
mexican restaurant at 7 pm in cupertino'
</i><br><br>Given that you have said this; <br> How about null. It is in
Mountain View; in Peninsula. There is a reservation at earlyNight.<br>
<select id="choice" name="attribute"><option selected="selected"
value="makeSelection">please choose</option>
<option value="yes">yes</option>
<option value="no">no</option></select><br><br><input type="button"
onclick="return sendChoice(eli,pincus,i want a mexican restaurant at 7 pm in
cupertino,instance,1)" value="Submit"></div>
I check your post, but i cant find any missing ")". The console doesnt tell you where to look?
I figured it out; it is because the arguments of the javascript function that get written on the updated page are strings and so need qoutes around them (one of them had spaces and thats why i didn't get a line number it messes up the parser)
This is my jsp code where I am trying to push some data in javaScript array.
<%
int proListSize = proList.size();
ProfileDAO proDAO = null;
for(int i = 0, j=1; i < proListSize; i++){
proDAO = (ProfileDAO)proList.get(i);%>
entireArray.push(<%= proDAO.getNetworkmapId()%> + ":"+<%=proDAO.getAssetId()%> + ":" + <%= proDAO.getCode()%>);
<%} %>
And this is the function where I am trying to use it by using pop function.
function GenDemographicTag() {
var ptag = "<!-- Begin "+networkNameToUpperCase+" -->\n" ;
var t = "";
if (WhiteTagLabelDomain) {
ptag += "<iframe src=\"http://"+WhiteTagLabelDomainTrim+"/jsc/"+folderName+"/dm.html?";
} else {
ptag += "<iframe src=\"http://"+cdnName+"/jsc/"+folderName+"/dm.html?";
}
ptag += "n="+networkId+";";
for(var i = 0;i< entireArray.length;i++){
var combinedString = entireArray.splice(1,1);
var rightSide = combinedString.split(':')[0];
var middle = combinedString.split(':')[1];
var leftSide = combinedString.split(':')[2];
t = "";
if ( $("proElementEnable_"+rightSide) && $("proElementEnable_"+leftSide).checked) {
if ( middle == "1") {
if ( $("zip").value.length <= 0) {
t = "0";
} else {
t = $("zip").value;
}
} else if ( $("targetList_"+rightSide) && $("targetList_"+rightSide).length > 0 && $("targetList_"+rightSide).options[0].value != "-1") {
t = makeProelementList($("targetList_"+rightSide));
}
ptag += leftSide+"=" + t+ ";";
}
proDAO = null;
}
ptag += "\" frameborder=0 marginheight=0 marginwidth=0 scrolling=\"no\" allowTransparency=\"true\" width=1 height=1>\n</iframe>\n<!-- end "+networkNameToUpperCase+" -->\n";
document.forms[0].tag.value = ptag;
}
Basically I am trying to get the data from proList and store it in javaScript array(entireArray)...so that I can use in the javascript function..but after doing the above I get a javaScript error as follow:
entireArray.push(3 + ":"+3 + ":" + d3);
entireArray.push(185 + ":"+5 + ":" + d4);
entireArray.push(2 + ":"+2 + ":" + d2);
entireArray.push(186 + ":"+5 + ":" + d9);
entireArray.push(183 + ":"+5 + ":" + d6);
entireArray.push(184 + ":"+5 + ":" + d7);
entireArray.push(187 + ":"+5 + ":" + da);
entireArray.push(445 + ":"+5 + ":" + db);
Reference Error:d3 is not defined.
what is the exact problem..?
The return type of splice is an ARRAY , so you can try following code
var combinedString = entireArray.splice(1,1);
var rightSide = combinedString[0].split(':')[0];
var middle = combinedString[0].split(':')[1];
var leftSide = combinedString[0].split(':')[2];
d3 should be in quotes. "d3"
You need to put the out of JSP in quotes.
entireArray.push(<%= proDAO.getNetworkmapId()%> + ":"+<%=proDAO.getAssetId()%> + ":" + '<%= proDAO.getCode()%>');