Related
I got this error when using uniGUI framework for executing JS code.
Cannot read property 'scrollView' of undefined
This property is used in this procedure.
procedure SetScrollboxSize(AFramem: TWPUnimFrame; ASize: Integer);
begin
if ASize > AFramem.ScrollBoxm.ClientHeight then
UniSession.JSCode(AFramem.Scrollboxm.JSName
+ '.scrollableBehavior.scrollView.getScroller().maxPosition.y = '
+ (ASize - AFramem.Scrollboxm.ClientHeight).ToString + ';')
else
UniSession.JSCode(AFramem.Scrollboxm.JSName
+ '.scrollableBehavior.scrollView.getScroller().maxPosition.y = 0;');
end;
Can you give me a hint where to search or where to start to fix this bug?
It's difficult to reproduce your error without the actual source code, but "Cannot read property '...' of undefined" is typical JavaScript error. I guess that TWPUnimFrame is some kind of component for displaying web content.
In your case you need to make sure that AFramem.Scrollboxm.JSName + '.scrollableBehavior' variable is assigned. You may try to output some information with console.log() and debug JavaScript code:
procedure SetScrollboxSize(AFramem: TWPUnimFrame; ASize: Integer);
var
code: string;
begin
code := 'console.log(' + AFramem.Scrollboxm.JSName + 'scrollableBehavior.scrollView); ';
if ASize > AFramem.ScrollBoxm.ClientHeight then
code := code +
AFramem.Scrollboxm.JSName +
'.scrollableBehavior.scrollView.getScroller().maxPosition.y = ' +
(ASize - AFramem.Scrollboxm.ClientHeight).ToString + ';'
else
code := code +
AFramem.Scrollboxm.JSName +
'.scrollableBehavior.scrollView.getScroller().maxPosition.y = 0;';
UniSession.JSCode(code);
end;
This is my very first question.
How can i run an "IF STATEMENT" in side the raw code of QZ tray where Var = print data [];
The below code works wonderful without IF STATEMENT, but the codes cannot parse once i use it.
var printData = [
'<xpml><page quantity="0" pitch="127.0 mm"></xpml>^AD\n',
'^O0\n'
'<xpml></page></xpml><xpml><page quantity="9" pitch="127.0 mm"></xpml>~MDELF,FORMAT_0\n',
'^E10.0\n',
'^L\n',
'C0,0000000000000000,+1,prompt_C0\n',
'C1,0000000000000000,+1,prompt_C1\n',
'C2,000,+1,prompt_C2\n',
'Lo,51,438,761,440\n',
'Lo,51,678,761,680\n',
'Lo,51,558,761,560\n',
'Lo,51,158,761,160\n',
'AH,320,31,1,1,0,0,'+ acs +'\n',
'BQ2,160,742,4,8,156,0,0,C^C0\n',
'AD,254,900,1,1,0,0,^C1\n',
'AA,439,440,1,1,0,0,Service\n',
'Lo,425,440,427,678\n',
'AA,442,560,1,1,0,0,Total No of Pieces\n',
'AA,439,684,1,1,0,0,Origin\n',
'AB,511,684,1,1,0,0,' + origin +'\n',
'AF,182,590,1,1,0,0,'+ destination+'\n',
'R49,13,762,999,3,3\n',
'E\n',
'^KFORMAT_0\n',
if (pcstart.length ==1)
{
premawb + postmawb +'0000'+ pcstart +'\n',
}
else {
premawb + postmawb +'000'+ pcstart +'\n',
}
pcstart + '\n',
'E\n',
'~P'+ copyPrint+'\n',
qz.print(config, printData).catch(displayError);
}
How can i run an "IF STATEMENT" in side the raw code of QZ tray
You can't mid-array, but you can add a ternary operator which does the same thing for a simple if/else statement:
pcstart.length == 1 ? '0000' : '000'
... and in context...
var printData = [
'<xpml><page quantity="0" pitch="127.0 mm"></xpml>^AD\n',
'...',
'^KFORMAT_0\n',
premawb + postmawb + (pcstart.length == 1 ? '0000' : '000') + pcstart + '\n',
pcstart + '\n',
'E\n',
'~P'+ copyPrint + '\n'
];
qz.print(config, printData).catch(displayError);
You can also call a function on the array element, so you may find it more desirable to roll your own pad(...) function and then call pad on the entire number or concatenated string... e.g:
premawb + postmawb + pad(pcstart, 4) +' \n',
I the above example, pad(...) is a function you make that can contain all the if/else statements you need and returns the formatted value.
sorry I just started with javascrippt and html and I am having trouble finding out what the unexpected identifier is?
here is my function
function fillSearchPlayer(data){
$('#searchPlayers tbody').html('');
for (var i = data.length - 1; i >= 0; i--) {
var p = data[i]
var item = '<tr><td>'p.firstname + ' ' + p.lastname'</td><td>'p.job'</td><td><button class="cbtn" onclick="requestPlayer("'+ p.identifier + '")">More</button></td></tr>'
$('#searchPlayers tbody').append('item');
}
}
maybe you guys could help me, it's saying its coming from the line that starts with "var item"
'<tr><td>'p.firstname look like you missed a plus sign over there. The other thing is .append('item'); - you probably intented to do .append(item);.
As the guys mentioned in the direct comments above you should try to use some templating engine instead of constructing the strings the way you did it.
I would recommend you to read these pieces:
Handlebars - simple and convenient template engine in JavaScript - give it a try!
Template strings in ES2016 - a cleaner way to do what you did with manual string concatenation
There are several errors. String concatenation works with +, and you're missing a semicolon.
Try:
function fillSearchPlayer(data) {
$('#searchPlayers tbody').html('');
for (var i = data.length - 1; i >= 0; i--) {
var p = data[i];
var item = '<tr><td>' + p.firstname + ' ' + p.lastname + '</td><td>' + p.job + '</td><td><button class="cbtn" onclick="requestPlayer("'+ p.identifier + '")">More</button></td></tr>';
$('#searchPlayers tbody').append('item');
}
}
The var item = ... item mixes variable and literal definitions without the real concatenation going on. Just put a + between each varying element to achieve your goal.
You need to enclose the concatenation operator around the p.job variable.
Your assignment should look like this...
var item = '<tr><td>'+p.firstname + ' ' + p.lastname+'</td><td>'+p.job+'</td><td><button class="cbtn" onclick=requestPlayer('+ p.identifier + ')>More</button></td></tr>'
I am saving table data to a json object. The table data is coming from txt inputs and textareas in the table cells.
I'm running into a problem with CR/LF characters in the JSON elements holding the textarea data. The JSON data gets saved to the database fine, but when I pass it back to the jQuery function that populates the table using that data, I get this:
SyntaxError: JSON.parse: bad control character in string literal at line 1 column 67 of the JSON data
var array = JSON.parse(notes),
in the console.
I put the JSON data in Notepad++ with Show All Characters on and the CR/LF was at column 67.
Here's a sample of JSON data that I'm working with:
[["","","",""],["","9/23/14","",""],["","30789 detail, x_vendor_no**CR/LF HERE**
20597 header","",""],["","99 del invalid x_vendor_no","",""],["","30780","",""],["","","",""],["","","",""],["","","",""]]
Is there a way to allow CR/LF in the data?
UPDATE
11684's suggestion to use replace to remove the \r part of the CRLF won't work. Here's why:
Here's the complete function that uses the JSON data:
(Updated to work with Update #2 code below)
function PopulateTaskTableWithNotes(tableID,notesArray) {
// JSON parse removed per answer suggestion
var r, c, note;
for (r = 0; r < notesArray.length; ++r) {
for (c = 0; c < notesArray[r].length; ++c) {
note = notesArray[r][c];
$('#' + tableID + ' tr:nth-child(' + (r + 1) + ') td:nth-child(' + (c + 1) + ')').children(':first-child').val(note);
}
}
}
I still get the error on the line that tries to parse the JSON data. The replace function apparently can't "find" characters within an array element.
UPDATE #2
Here's how I am creating the array:
var siteID = $('#ddlUserSites option:selected').val(),
numRows = $('#' + tableID + ' tr').length,
numCols = $('#' + tableID).find('tr:first th').length,
notesArray = new Array(numRows),
rowNum = 1,
note = '',
colNum;
while (rowNum <= numRows) {
notesArray[rowNum] = new Array(numCols);
// Reset colNum for next row iteration
colNum = 1;
while (colNum <= numCols) {
note = '';
if ($('#' + tableID + ' tr:nth-child(' + rowNum + ') td:nth-child(' + colNum + ')').children(':first-child').is('input,textarea')) {
note = $('#' + tableID + ' tr:nth-child(' + rowNum + ') td:nth-child(' + colNum + ')').children(':first-child').val();
}
notesArray[rowNum][colNum] = note;
//console.log('Note for rowNum ' + rowNum + ', colNum ' + colNum + ': ' + note);
colNum++;
}
// Remove first element in current row array
notesArray[rowNum].shift();
rowNum++;
}
// Remove first element in array
notesArray.shift();
JSON.stringify(notesArray); // Added per an answer here
console.log('Final notesArray: ' + $.toJSON(notesArray));
$.ajax({
data: {saveTaskNotes: 'true', userID:userID, siteID:siteID, taskTable:tableID, notes:notesArray},
success: function(data) {
console.log('Save task notes data: ' + data);
}
});
The "Final notesArray" console output looks fine, but now, with stringify added, the function above (PopulateTaskTableWithNotes) console output shows that it's reading through every character in the array as a separate element!
Maybe this will help too, as far as what's happening to the data between the creating and reading functions: the array is being saved to a single MySQL database field and then retrieved for the PopulateTable function via $.ajax() (on both ends).
Having said that, do I need to look at what I'm doing with/to the array in the PHP code?
UPDATE #3
Here's the PHP function that takes the data in and writes to the MySQL db:
function SaveTaskNotes($userID,$siteID,$taskTable,$notes) {
$notes = json_encode($notes);
$insertUpdateTaskNotesResult = '';
$insertTaskNotes = "INSERT INTO userProgress (userProgressUserID,userProgressSiteID,userProgressNotesTable,userProgressNotes) values ($userID,$siteID,'" . $taskTable . "','" . $notes . "')";
$log->lwrite('$insertTaskNotes: ' . $insertTaskNotes);
$resultInsertTaskNotes = #mysqli_query($dbc,$insertTaskNotes);
if ($resultInsertTaskNotes) {
$insertUpdateTaskNotesResult = 'insertTaskNotesSuccess';
} else {
if (mysqli_error($dbc) != '') {
$log->lwrite('INSERT TASK NOTES: An error occurred while attempting to add the task notes. Query: ' . $insertTaskNotes . ', mysqli_error: ' . mysqli_error($dbc));
}
$insertUpdateTaskNotesResult = 'insertTaskNotesFail';
}
echo $insertUpdateTaskNotesResult;
}
And here's the function that gets the data from the db and sends it to the above $.ajax function:
function GetUserTaskNotes($userID,$siteID,$taskTableID) {
$queryGetUserTaskNotes = "SELECT userProgressNotes FROM userProgress WHERE userProgressUserID = $userID AND userProgressSiteID = $siteID AND userProgressNotesTable = '" . $taskTableID . "'";
$log->lwrite('$queryGetUserTaskNotes: ' . $queryGetUserTaskNotes);
$resultGetUserTaskNotes = #mysqli_query($dbc,$queryGetUserTaskNotes);
if ($resultGetUserTaskNotes) {
$taskNotes = mysqli_fetch_assoc($resultGetUserTaskNotes);
$log->lwrite('Retrieved $taskNotes[\'userProgressNotes\']: ' . $taskNotes['userProgressNotes']);
echo $taskNotes['userProgressNotes'];
} else {
if (mysqli_error($dbc) != '') {
$log->lwrite('GET TASK NOTES: An error occurred while attempting to retrieve the task notes. Query: ' . $queryGetUserTaskNotes . ', mysqli_error: ' . mysqli_error($dbc));
}
echo 'getTaskNotesFail';
}
}
In both the save and get functions the $log output shows that the array never changes (with the above js/php code) and pasting the array in to notepad++ shows that the CR/LF is still there throughout.
Don't use JSON.parse, the data is already JSON and Javascript can work with it.
You only need it when passing a string, imagine JSON.parse() beeing like string2json().
I think this might already be a solution to your problem, I've never had issues with new line characters.
As Luis said, the problem is not your client (Javascript, jQuery), besides the JSON.parse, but the providing site is wrong.
Example for PHP:
<?php
echo json_encode(array("test" => "
x"));
PHP properly escapes the characters:
{"test":"\r\n\r\n\r\nx"}
But the source of your data is providing malformed JSON.
To fix the JSON issue, either use prepared statements or use:
$notes = str_replace('\', '\\', json_encode($notes)); // in SaveTaskNotes
Well, the error is on the input data (showed in question). You can't have an CR or LF inside a literal in a JSON string. What you can have are that chars escaped as \r \n. The problem is on other side, where escaped codes are replaced by actual chars and therefore the full JSON string becomes invalid.
i'm doing an application with ajax using jQuery and some other tools, and in some part i want to retrieve data with ajax using a classic ASP backend, i saw that exists a good implementation of a JSON class in AXE (Asp extreme edition) framework, and i used it but currently i don't understand how to use it well.
Edit: based on the correct answer of JSON.Stringify fails on Scripting.Dictionary objects Thread, i decided to make a custom function to process Recordsets.
Edit 2: Now i'm losing the value data when call JSON.stringify inside function JSONStringify(object).
when the Recordset is passed as value to JSONStringify everything is ok but when JSON.stringify is executed, the "value" parameter that must contain the recordset becomes undefined
What i'm expecting (example)
passing a Recordset with from a SQL query SELECT name, tel FROM users a see an output like this
[
{"name":"Jonh Smith", "tel":"12345678"},
{"name":"April Michelson", "tel":"77788802"},
...
]
passing a Dictionary and see something similar based in the elements declared in dictionary.
{
"element1":"value1",
"element2":"value2",
"element3":"value3",
"element4":"value4",
"element5":"value5"
}
and if i like to support other type object i can do it expanding the function
Source Code
getcatalogos.asp
<!--#include file="../includes/conexion.asp" -->
<!--#include file="../includes/json2.asp" -->
<!--#include file="../includes/json-stringify-parser.asp" -->
<%
Response.ContentType = "application/json"
dim aVals(2)
function getCatalogo(tipo, params)
Dim oConn,oCmd,sSQL,oRs,cont2
Dim aData,oPar,cont
dim Info
set oConn = Server.CreateObject("ADODB.Connection")
set oCmd = Server.CreateObject("ADODB.Command")
sWhere = ""
oConn.ConnectionString = strcon
oConn.Open
Set oCmd.ActiveConnection = oConn
select case tipo
case "g"
sSQL = " SELECT cve_gr, descr FROM gr ORDER BY descr ;"
case "z"
sSQL = " SELECT cve_zn, descr FROM zn WHERE cve_gr = ? ORDER BY descr ;"
if IsArray(params) Then
Set oPar=oCmd.CreateParameter (params(0),129,1,2,params(1))
oCmd.Parameters.Append(oPar)
End if
case else
getCatalogo = false
exit function
end select
oCmd.CommandText = sSQL
Set oRs = oCmd.Execute()
if Not oRs.EOF Then
response.write(JSONStringify(oRs))
getCatalogo = true
else
getCatalogo = false
end if
oConn.Close
end function
aVals(0) = "cve_gr"
aVals(1) = request.querystring("gr")
if Not getCatalogo(request.querystring("t"),aVals) Then
%>error<%
end if
%>
json-stringify-parser.asp
<!--#include file="vbsTyper.asp" -->
<script runat="server" language="JScript">
function JSONStringify(object) {
VBSTypeName(object);
return JSON.stringify(object,stringifyData);
}
function stringifyData(holder, key, value) {
var sType = '';
var result;
//response.write('pre...holder=' + holder + ',key=' + key + ',value=' + value);
sType = VBSTypeName(value);
//response.write('post =' + sType);
//response.write(sType);
switch(sType){
case 'Dictionary':
result = '{';
for(var enr = new Enumerator(value); !enr.atEnd(); enr.moveNext()){
key = enr.item();
result += '"' + key + '": ' + JSON.stringify(value.Item(key));
};
result += '}';
return(result);
break;
case 'Recordset':
response.write('here!!!');
var sTemp = '';
result = '{';
while(!value.EOF){
if(Len(result) > 0){
result += ',';
}
result += '{';
for (var i = value.Fields.Count - 1; i >= 0; i--){
if(len(sTemp) > 0){
sTemp += ',';
}
sTemp += '"' + value.Fields(i).name + '":' + JSON.stringify( value.Fields(i).value);
};
result += '}';
}
result += '}';
return result;
break;
default:
//response.write(sType);
return(value);
}
// return the value to let it be processed in the usual way
return result;
}
</script>
vbsTyper.asp
<%
Function VBSTypeName(Obj)
dim sType
sType = Cstr(TypeName(Obj))
response.write(sType)
VBSTypeName = sType
End Function
%>
This:
response.write(JSON.stringify(oRs))
Should read something like this:
Do Until oRS.EOF
response.write(JSON.stringify(oRs("cve_gr") & ":" & oRs("descr"))
oRS.MoveNext
Loop
kind of achieve it...
Short version: i had to modify the json2.asp and hack the stringify() function definition to make it works.
Long Version
later of see every line of code and giving up on the problem. i decided to take a look into json2.asp (AXE Framework) and try to see what it happening there.
look what i see:
from the lines 682 to 687 theres a validation if a custom stringy parser is found but later doesn't do anything ... only returns the Object value.
there's speculation from here, because i don't understand well how works every Javascript implementation, but implying that the original code runs well, that a standart javascript interpreter (read everything else but microsoft here) will force a serialization of the object in this sutuation, but the JScript interpreter try to parse the object and pass the value as null. resulting in that every function that uses a custom stringyfier can't read the object passed in the function.
what i did to resolve ok i inserted this chunk of code before line 688, forcing to execute the custom stringyfier with value directly passed as argument avoiding the implicit parsing.
// Hack & patch to deliver the stringify-ing of the object correctly
// IDK if this is CORRECT or dont but it works in VbScript
if(replacer){
var textval = rep(this,'',value);
value = textval;
}
later i had to do some changes in json-stringify-parser.asp because i had to fix some bugs resulting in this code
<!--#include file="vbsTyper.asp" -->
<script runat="server" language="JScript">
function JSONStringify(object) {
//VBSTypeName(object);
return JSON.stringify(object,stringifyData,4);
}
function stringifyData(holder, key, value) {
var sType = '';
var result;
//response.write('pre...holder=' + holder + ',key=' + key + ',value=' + value);
sType = VBSTypeName(value);
//response.write('post =' + sType);
//response.write(sType);
switch(sType){
case 'Dictionary':
result = '{';
for(var enr = new Enumerator(value); !enr.atEnd(); enr.moveNext()){
key = enr.item();
result += '"' + key + '": ' + JSON.stringify(value.Item(key));
};
result += '}';
return(result);
break;
case 'Recordset':
//response.write('here!!!');
var sTemp;
result = '';
while(!value.EOF){
if(result.length > 0){
result += ',';
}
result += '{';
sTemp=''
for (var i = 0; i < value.fields.Count; i++){
if(sTemp.length > 0){
sTemp += ',';
}
//response.write("i=" + i + ",");
sTemp += '"' + value.fields.item(i).name + '":' + JSON.stringify( value.fields.item(i).value);
};
result += sTemp + '}';
value.moveNext();
}
result = '{' + result + '}';
return result;
break;
default:
//response.write(sType);
return(value);
}
// return the value to let it be processed in the usual way
return result;
}
</script>
the part to parse a Recordset works, the part to parse a dictionary is same like the shown in JSON.Stringify fails on Scripting.Dictionary objects (a.k.a. i haven't tested yet) but for now i'm done with this.
testing my changes with a recordset object results in this output
"{
{\"clave\":\"BC\",\"descripcion\":\"Cal\"},
{\"clave\":\"CT\",\"descripcion\":\"Center\"},
{\"clave\":\"NE\",\"descripcion\":\"Norw\"},
{\"clave\":\"NO\",\"descripcion\":\"Nore\"},
{\"clave\":\"NT\",\"descripcion\":\"North\"},
{\"clave\":\"OC\",\"descripcion\":\"East\"},
{\"clave\":\"OR\",\"descripcion\":\"West\"},
{\"clave\":\"PE\",\"descripcion\":\"Pen\"},
{\"clave\":\"SE\",\"descripcion\":\"Southe\"},
{\"clave\":\"ZM\",\"descripcion\":\"Met\"}
}"
Questions Left
question that i have left withis kind of hack.
it's Ok that the output has (") character at the beggining and the
end and i everything else has escape sencuences ?? or it's something
that should not occurs.
this kind of hack is really wrong ... i can do it better, in this
kind of situation ?
it's something wrong in my conclusion or arguments ??