Below is the code.
under the function there is a resultContainer.innerHTML that populates a list of QR codes scanned. How can $_POST the values in PHP so that I can send it in an email format? I tried adding a name within the div (<div **name="qrOutput"**>[${countResults}] - ${qrCodeMessage}</div>) but PHP does not pick it up. Only returns an empty string.
I also tried giving the <div id="qr-reader-results"></div> element a name but because the output is within another div inside this div I also got an empty result.
Thanks a lot for any help.
<!-- start -->
<div id="qr-reader" style="width:500px"></div>
<div id="qr-reader-results"></div>
<div id="root"></div>
<script>
function docReady(fn) {
// see if DOM is already available
if (document.readyState === "complete" ||
document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
docReady(function() {
var resultContainer = document.getElementById('qr-reader-results');
var lastResult, countResults = 0;
function onScanSuccess(qrCodeMessage) {
if (qrCodeMessage !== lastResult) {
++countResults;
lastResult = qrCodeMessage;
resultContainer.innerHTML += ***`<div">[${countResults}] - ${qrCodeMessage}</div>`;***
}
}
var html5QrcodeScanner = new Html5QrcodeScanner(
"qr-reader", {
fps: 10,
qrbox: 250
});
html5QrcodeScanner.render(onScanSuccess);
});
</script>
<p id="QRout"></p>
You can store your results in an other variable when you add it to the DOM.
Declare a variable to store your results
var myResults = [];
When you add the result to the DOM add also the results in array variable
// ...
resultContainer.innerHTML += `<div>[${countResults}] - ${qrCodeMessage}</div>`;
myResults.push({count: countResults, message: qrCodeMessage})
Then you can use myResult var on a POST request
myCustomPostFunction('/yourUrl/', myResult);
The "myCustomPostFunction" will depend on the way you want to send the data
Check this codepen: https://codepen.io/zecka/pen/VwKNpze
Post request like a form submit
If you want to send the data to the current page like a form post, you can find an example here: https://stackoverflow.com/a/133997/2838586
Post request to a rest api
Fetch: POST json data
I have a set of scripts that I'm using that interact with each other. I use a client, user event and suitelet script to create a button that, when pressed, opens a popup with a list of items filtered by vendor.
It works fine when I'm in edit however when I use it while creating a record problems arise. Since the record to be created has no vendor or id I can't retrieve an item by vendor. What I'm trying to do is to have the Suitelet retrieve the info from the vendor field that is entered prior to it being saved. Therefore I can filter all the items by vendor and add the necessary items in one go. Is this possible? Am I able to access the info before it is submitted.
Below are the Client and Suitelet. The User Event is just a call to the suitelet so for the sake of brevity I left it out.
Client Script
function addItemButtonCallback(data){
nlapiSelectNewLineItem('item');
nlapiSetCurrentLineItemValue('item', 'item', data);
nlapiCommitLineItem('inventoryitem');
}
function addItemButton() {
var id = nlapiGetFieldValue('id');
if (id != "") {
var url = nlapiResolveURL('SUITELET', 'customscript_val', 'customdeploy1') + '&poId='+id;
window.open(url, '_blank', 'width=500,height=500');
}
}
Suitelet
function suitelet(request, response){
if(request.getMethod() == 'GET') {
var form = nlapiCreateForm('Add Item');
form.addSubmitButton('Submit');
var itemfield = form.addField('custpage_val', 'select', 'Item');
var id = request.getParameter('id');
var rec = nlapiLoadRecord('purchaseorder', id);
var vend = rec.getFieldValue('entity');
var search = nlapiSearchRecord(...search parameters...);
for (result in search){
if (search[result].getValue('vendor') == vend){
itemfield.addSelectOption(search[result].id, nlapiLookupField('inventoryitem', search[result].id, 'itemid'));
}
}
response.writePage(form);
} else {
var data = request.getParameter('custpage_item');
response.write('<html><body><script>window.opener.addItemButtonCallback("'+data+'"); window.close();</script></body></html>');
}
}
Use nlapiGetFieldValue('entity') on the clientscript and pass it to the Suitelet using a query parameter just like you are doing with poId (if you do this you might not even need poId after all + no need to load the record on the suitelet).
Also, you might want to optimize your code by running one search passing an array of itemids instead of calling nlapiLookupField for each item.
You might need to modify your beforeLoad so the entity is inserted dynamically when the button is pressed (I cant remember if clientscript button does this) . Something like this:
var suiteletURL = nlapiResolveURL('SUITELET', 'customscript_val', 'customdeploy1');
var script = "var entity = nlapiGetFieldValue('entity'); var url = '" + suiteletURL + "'&entityId=' + entity;window.open(url, '_blank', 'width=500,height=500')";
var button = form.addButton('custpage_addItemButton', 'Add Item', script);
I want the JS to be able to save the comment of the inputted name and comment and for it to be displayed after clicking the Save Comment button underneath the Comments at the bottom.
It does that but the name and the comment are side by side instead of on top of each other and looks confusing
// utility functions for localstorage
function setObject(key, value) {
window.localStorage.setItem(key, JSON.stringify(value));
}
function getObject(key) {
var storage = window.localStorage,
value = storage.getItem(key);
return value && JSON.parse(value);
}
function clearStorage() {
window.localStorage.clear();
}
// Clear inputfields and localstorage
function clearComment(){
$('#txt1').val('');
$('#namebox').val('');
clearStorage();
}
function saveComment(){
var cText = $('#txt1').val(),
cName = $('#namebox').val(),
cmtList = getObject('cmtlist');
if (cmtList){
cmtList.push({name: cName, text: cText});
setObject('cmtlist', cmtList);
}else{ //Add a comment
setObject('cmtlist', [{name: cName, text: cText}]);
}
bindCmt();
}
function bindCmt(){
var cmtListElement = $('#cmtlist'),
cmtList = getObject('cmtlist');
//Out with the old
cmtListElement.empty();
//And in with the new
$.each(cmtList, function(i, k){
cmtListElement.append( $('<p><span>'+ k.name +'</span>'+ k.text +'</p>') );
});
}
//Get the comments on page ready
$(function(){
bindCmt();
});
it looks like this:
You could add an html break <br> to the line below:
cmtListElement.append( $('<p><span>'+ k.name +'</span><br>'+ k.text +'</p>') );
I developed an ajax file uploader and it works great if the one instance is on the page. I'm trying to convert it to allow multiple instances, and it almost works, EXCEPT, when I'm uploading multiple files in one form, it uploads the first file fine, but then for all subsequent files, for some reason it points forward to the next file reader from the second form instance. If I upload using the last (second) instance of the upload form, multiple files upload fine. But if I try uploading with the first instance, it will upload the first file, but all subsequent files get sent to the empty file input from the second instance. I can't understand why. I'm using unique id names throughout the upload form and referencing that unique id throughout the javascript functions. I'll try to include all the necessary bits of code below.
The forms are generated by PHP. The php var $uid is a randomly generated unique id that I use throughout. First, the initialization of the upload function is output to the page in a <script> tag:
'<script> '.
'jQuery(document).ready(function($){ '.
'var myup_'.$uid.' = new MyUp({ '.
'form_id: "myup_form_'.$uid.'", '.
'uid: '.$uid.', '.
'container: "'.$name.'", '.
'table: "'.$style.'", '.
'iconcolor: "'.$iconcolor.'", '.
'maxsize: '.$maxsize.', '.
'permitted: '.$permitted.', '.
'prohibited: '.$prohibited.', '.
'fixed: '.$fixedsetting.', '.
'pathcheck: "'.$pathcheck.'", '.
'uploader: '.$uploader.', '.
'loading: "'.my_url.'/lib/img/ajax.gif" '.
}); '.
'}); '.
'</script>';
Obviously all those variables for my settings are defined earlier. With multiple instances on the page, it reads the settings correctly for each different instance. They are successfully showing up with different styles, icon colors, file type permissions, max file size settings, etc. All that works with multiple instances.
Now the form:
'<div class="myup_container" style="'.$inlinestyle.'">'.
'<form name="myup_form_'.$uid.'" id="myup_form_'.$uid.'" action="javascript:void(0);" enctype="multipart/form-data">'.
'<input type="hidden" id="upload-actionpath-'.$uid.'" value="'.$fixed.'" data-basename="'.$basename.'" data-start="'.$start.'" />'.
'<div class="myup_buttons_container" style="text-align:right;">'.
'<span class="myup_wrapper" style="text-align:left;">'.
'<input type="file" name="myup_files_'.$uid.'[]" id="myup_files_'.$uid.'" class="hidden_browse"'.$multiple.' />'.
'<span class="add_files">'.$addfiles.'</span>'.
'<span id="submit_upload_'.$uid.'">'.$uploadlabel.'</span>'.
'</span>'.
'</div>'.
'</form>'.
'<div id="myup_files_container_'.$uid.'" class="myup_files_container"></div>'.
'<span id="my_removedfiles_'.$uid.'" style="display:none;"></span>'.
'</div>';
So that's a pared down version of it. The instance in the script tag, containing the settings, and the html form, are output by a shortcode. So multiple shortcodes on the page will output multiple instances of the MyUp function.
Here's what I hope are all the pertinent bits of the javascript functions (it's long, sorry, but I removed a ton of stuff):
jQuery(document).ready(function($)
{
// throughout, the var fuid will refer
// to the php var $uid from the html form and instance settings
function myupRemove(id, filename, fuid)
{
// handle files the user removes from the input field
// before submitting the upload
}
function MyUp(config)
{
this.settings = config;
this.fuid = this.settings.uid;
this.file = "";
this.browsed_files = [];
var self = this;
MyUp.prototype.myupDisplay = function(value)
{
this.file = value;
if(this.file.length > 0)
{
/* this is a really long bit of code
* that i'll spare you, but basically I iterate
* through all the files in the input field
* and put them dynamically into a table
* and drop the table onto the page
* so the user can rename them, remove them before upload,
* and then watch the status bar for each file as it uploads.
* This portion of the code works fine with multiple instances.
*/
}
}
// Create Unique ID
MyUp.prototype.uid = function(name)
{
// Here I generate a unique ID for each file,
// and prepend it with the Instance's unique id (i.e., this.fuid)
return this.fuid+'_'+name.replace(/[^a-z0-9\s]/gi, '_').replace(/[_\s]/g, '_');
}
// Get File Extension
MyUp.prototype.ext = function(file, lowercase)
{
return (/[.]/.exec(file)) ? (lowercase ? /[^.]+$/.exec(file.toLowerCase()) : /[^.]+$/.exec(file)) : '';
}
// Format File Size
MyUp.prototype.nicesize = function(fileSize)
{
// a bunch of code to format the file size then...
return niceSize;
}
// Attribute FileType Icons
MyUp.prototype.icon = function(icon_ext, color)
{
// a bunch of arrays to determine
// which file type icon to display in the table
}
//File Reader
MyUp.prototype.read = function(e)
{
if(e.target.files)
{
// references the myupDisplay function
// where I add the files to a table
self.myupDisplay(e.target.files);
self.browsed_files.push(e.target.files);
}
}
function addEvent(type, el, fn)
{
if(window.addEventListener)
{
el.addEventListener(type, fn, false);
}
else if(window.attachEvent)
{
var f = function()
{
fn.call(el, window.event);
};
el.attachEvent('on' + type, f)
}
}
// Collect File IDs and Initiate Upload for Submit
MyUp.prototype.starter = function()
{
if(window.File && window.FileReader && window.FileList && window.Blob)
{
var browsed_file_id = $("#"+this.settings.form_id).find("input[type='file']").eq(0).attr("id");
document.getElementById(browsed_file_id).addEventListener('change', this.read, false);
document.getElementById('submit_upload_'+this.fuid).addEventListener('click', this.submit, true);
}
else alert(browser_cant_read_message);
}
// Begin Upload on Click
MyUp.prototype.submit = function()
{
self.begin();
}
// Initiate Upload Iterator
MyUp.prototype.begin = function()
{
if(this.browsed_files.length > 0)
{
for(var k=0; k<this.browsed_files.length; k++)
{
var file = this.browsed_files[k];
this.myupAjax(file,k);
}
this.browsed_files = [];
}
else alert(no_files_chosen_message);
}
// Ajax Upload
MyUp.prototype.myupAjax = function(file,i)
{
if(file[i]!== undefined)
{
var id = file_id = self.uid(file[i].name),
rawname = file[i].name.substr(0, file[i].name.lastIndexOf('.')) || file[i].name,
extension = self.ext(file[i].name, false),
browsed_file_id = $("#"+this.settings.form_id).find("input[type='file']").eq(0).attr("id");
path = this.settings.fixed ? this.settings.fixed : String($('input#upload-actionpath-'+this.fuid).val()),
pathcheck = String(this.settings.pathcheck),
removed_file = $("#"+id).val(),
newname = String($('input#rename_upfile_id_'+id).val()),
new_name = newname === '' || newname === 'undefined' || newname === undefined ? file[i].name : newname+'.'+extension,
removed = this.settings.removed,
loading = this.settings.loading,
fixedchars = this.settings.fixed;
// if the file is removes, skip to the next file
if(removed_file !== '' && removed_file !== undefined && removed_file == id) self.myupAjax(file,i+1);
else
{
var myupData = new FormData();
myupData.append('upload_file',file[i]);
myupData.append('upload_file_id',id);
myupData.append('max_file_size',this.settings.maxsize);
myupData.append('upload_path',path);
myupData.append('new_name',new_name);
myupData.append('extension',extension);
myupData.append('uploader',this.settings.uploader);
myupData.append('act','upload');
myupData.append('nonce',myup.nonce);
$.ajax(
{
type : 'POST',
url : myup.ajaxurl+'?action=myup-uploads',
data : myupData,
id : id,
fuid : this.fuid,
new_name : new_name,
rawname : rawname,
extension : extension,
path : path,
pathcheck : pathcheck,
removed : removed,
loading : loading,
fixedchars : fixedchars,
cache : false,
contentType : false,
processData : false,
beforeSend : function(xhr, settings)
{
// I added this alert because it shows me that when I'm using the first instance
// after the first file uploads, it starts looking to the file input field
// from the second instance
alert('path: '+settings.path+' pathcheck: '+settings.pathcheck);
// in here I do a bunch of security stuff before uploading
},
xhr: function()
{
// my progress bar function here
},
success : function(response)
{
setTimeout(function()
{
if(response.indexOf(id) != -1)
{
// do success stuff, like green checkmark, remove table row, etc.
}
else
{
// do failure stuff, like red x and error message
}
// AND HERE IS THE IMPORTANT PART
// THIS SAYS TO GO ON TO THE NEXT FILE IN THE ARRAY
// BUT WHEN USING THE FIRST INSTANCE
// IT SENDS US TO THE SECOND INSTANCE'S FILE READER
// if I'm uploading with the second form it's fine
if(i+1 < file.length) self.myupAjax(file,i+1);
},500);
}
});
}
}
}
this.starter();
}
window.MyUp = MyUp;
window.myupRemove = myupRemove;
});
Note the comment block toward the end of the above code snippet, where the comment is in all caps. That's where it completes the ajax upload for a file, then sends us back to do the next one.
So, basically, to reiterate, if I have two forms on the page, when I use the second form, everything works fine. When I use the first form, the first file will upload fine, but then it starts looking for the next file in the input field from the second instance.
Is there a relatively simple solution for this?
In the posted code, the constructor function declares all prototype methods. This causes them to be overridden each time a new MyUp object is created, and they will use the configuration from the last one.
function MyUp(config) {
/// ...
var self = this;
MyUp.prototype.foo = function() {
// use `self`
};
}
Instead, you should declare the methods once and use the this reference to obtain any attached objects:
function MyUp(config) {
/// ...
}
MyUp.prototype.foo = function() {
// use `this`
};
If you need static members for the class (methods or variables that are not attached to any instance), you can declare them as fields of the function, if they are to be used publicly - MyUp.begin = function() {}. Or inside the module, if they are private:
(function() {
var uploadsInProgress = 0;
// declare MyUp and use uploadsInProgress; it will be hidden from customer code
window.MyUp = MyUp;
})();
I am not completely sure if this will resolve the upload issues, but it will definitely let you keep your sanity when instantiating multiple objects.
Well I couldn't get it to work the way Alex Gyoshev suggested (deficiency on my part no doubt), so I decided to get rid of the object/prototype route altogether. Instead of creating instances in the form, I declare a MyUpConfig variable in the global space, as an empty array. Then in each html form, I add MyUpConfig['.$uid.'] = and then my array of settings.
Then in the js file I bind each form's file input and submit events to the unique id, and store each input field's file data in an array like this: TheFiles[uid] = files. So when the upload submit occurs, it gets the uid from the upload button element, and only attempts to upload the files stored in the array matching that unique id.
I now have it working with multiple upload forms on the same page. They can each be running simultaneously without interference.
I'm trying to make a javascript function to change the value of a parameter in the URL with the value inputed in a text box, with no luck. That's because I'm note a code designer but a graph one.
this is the URL where I need to change the "City" parameter:
http://server/ad_new_customer.php?&city=&uri=http://server/adauga_exp.php
I am generating data in the input text box through a MySQL query with jQuery like this:
<input type='text' id='city' name='city' style="width:190px; align:left;" value="<?php echo $city; ?>" /> </td>
<script type="text/javascript">
//change the value of parameter in the URL function
function changeURI(key, value) {
var query = document.location.search.substring(1);
var query_q = query.split("?");
var vars = query_q[1].split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == key) {
vars[i] = pair[0] + "=" + value;
}
}
return vars.join("&");
}
//jQuery making the auto-suggestion query for the input ID
$().ready(function() {
$("#city").autocomplete("core/exp_city.php", {
width: 340,
matchContains: true,
selectFirst: false
}).return(changeURI("city", this.value}));
});
</script>
How can I make it change the value the parameter on selected value?
Please advise, again, a humble designer.
Thank you!
L.E.
I have made an workaround, changed the changeURI() function with this one:
function changeURI(key, value)
{
key = escape(key); value = escape(value);
var kvp = document.location.search.substr(1).split('&');
var i=kvp.length; var x; while(i--)
{
x = kvp[i].split('=');
if (x[0]==key)
{
x[1] = value;
kvp[i] = x.join('=');
break;
}
}
if(i<0) {
kvp[kvp.length] = [key,value].join('=');
}else{
//this will reload the page, it's likely better to store this until finished
document.location.search = kvp.join('&');
}
}
Found on StackOverflow and call it from the jQuery query with the $.result() function:
<script type="text/javascript">
$().ready(function() {
$("#city").autocomplete("core/exp_city.php", {
width: 340,
matchContains: true,
selectFirst: false
}).result(function() {changeURI("city",this.value)});
});
</script>
What error are you getting? are you getting any javascript error? Also, try changing your code to some thing like
url = url.replace(new RegExp("city=", 'g'), "city="+value).
Also, The URL written in the question should not have & before city parameter as the first parameter starts with a ?, so the URL should be :
http://server/ad_new_customer.php?city=&uri=http://server/adauga_exp.php
Check if that was the issue.
In your example, document.location.search.substring(1) is already getting rid of the question mark: it should return &city=&uri=http://server/adauga_exp.php. Then doing a split on "?" and trying to take the second array element should return undefined, because there are no longer any "?" characters. Skip straight to var vars = query.split("&") at that point, and the rest looks okay to me.