Hi i have many forms inside multiple pages all of them the with the same id (success message) after submitted and same class names when i'm sending the form which e.g inside home page i put element selector through id with Page PATH with match regex something like that \/(en|es)\/ it works good without problem ... but when i'm going to page www.something.com/send-something/233?search=profile the form submitted through old id which was for home page i tried to inject custom javascript something like :
function() {
var els = document.querySelectorAll('#sendReqSurgyForm1');
for (var i = 0; i < els.length; i += 1) {
if (els[i] === {{Page URL}}) {
return i;
}
}
return '(nothing sent)';
}
with adding matching Page URL with match regex something like that to https:\/\/www\.something\.com\/(ar|en)\/send-something\/[0-9]+\?source=[a-zA-Z]+\_?[a-zA-Z]+
to matching the url: www.something.com/send-something/233?search=profile
the trigger always works with home page but trigger which located in www.something.com/send-something/233?search=profile not success and the result of javascript always returns nothing sent .. please help to fix this problem
Hi the Answer is SPA Angular using SPA so it can be multiple form with the same component so i solved this problem through setting id for every form with different urls
for example if you have multiple forms in angular inside multiple routing page as i explained in the main topic question .. to fix this problem you can setting id for every form submissions through js by setting new id for every form submission by setting Attribute for id based different urls.
main_id = exampleForm
function(){
var ids = document.getElementById("exampleForm");//main id
var current_url = window.location.href;//current url of visitor
var dir_match = location.pathname+location.search;//the path of website after .com
var send_req = 'https://www.example.com/'+dir_match.match(/[ar][r]|[en]n/)+'/surgery-request/'+dir_match.match(/[0-9]+/)+'?source=profile';//link1 which have form1
var send_req2 = 'https://www.example.com/'+dir_match.match(/[ar][r]|[en]n/)+'/surgery-request/'+dir_match.match(/[0-9]+/)+'?source=profile2';//link2 which have form2
var home_url = 'https://www.example.com/'+dir_match.match(/[ar][r]|[en][n]/)+'/';//link3 which have form3
if(current_url == send_req){
/* if current_url equal to link1 set new id e.g = `forms_req_surgery` */
last_send_req = ids.setAttribute("id", "forms_req_surgery");
var elm = document.getElementById('forms_req_surgery');
var last_var = elm.id;/* get the name of id */
return last_var; // return the name of id after changed set
}else if(current_url == home_url){
last_home_url = ids.setAttribute("id", "home_req");
var elm2 = document.getElementById('home_req');
var last2_var = elm2.id;
return last2_var;
}else if(current_url == send_req2){
last_send_req2 = ids.setAttribute("id", "forms_req_surgery2");
var elm3 = document.getElementById('forms_req_surgery2');
var last3_var = elm3.id;
return last3_var;
}
}
i'm creating a form of inscription and i want to get info from a first page to show in a second one. I've tried to use local storage, but it doesn't work.
I've tried to test in the same page, which works, but when i try it with the localstorage, it doesn't work, and when i click on submit it reloads the page and nothing happens
Here is the code for the first page:
function rform()
{
document.getElemeentByName('insc').reset;
}
function client()
{
var sexe=document.getElemeentByName('gender');
var userT=document.getElementById('choice').selectedIndex;
var name = document.getEelementById('name').value;
localStorage.setItem('name',name)
if (userT[1] || userT[2] &&sexe[0].checked )
{
var choice = document.getElementById('choice').value;
localStorage.setItem('choice',choice)
else
{
var res = document.getElementById('choice').value + 'e';
localStorage.setItem('choice',choice)
}
return false;
}
And the second page:
<span id="result"></span>
<script type="text/javascript">
document.getElementById("result").innerHTML= 'welcome '
+localStorage.getItem('name')+ ' you are '
+localStorage.getItem('choice');
</script>`
I get nothing in the second page, but expect to get a welcome message with the name and the user type
var choice = document.getElementById('choice').value;
localStorage.setItem('choice','choice')
This isn't setting the value of Choice into localStorage, this is simple setting the value of localStorage named Choice to the string "Choice".
Should be;
var choice = document.getElementById('choice').value;
localStorage.setItem('choice',choice);
I have a main page with a popup window.
<textarea class="form-control item"></textarea>
<button type="button" class="btn btn-primary" name="name">Send</button>
There is also a second page. (/conclusion/main)
<textarea id="retro" style="height: 200px; width: 800px"></textarea>
I enter the text in the window and send. The window should close and the text should be sent to the second page and the text should be saved in the field "textarea". Even if they close the page or reload, the text should remain in the second page.
This code allows you to save, but after closing the page, does not save
(function(){
var textarea = document.getElementById('retro');
if (localStorage.retro)
{
textarea.value = localStorage.retro;
}
textarea.onchange = function()
{
localStorage.retro = this.value;
}
})();
Sends from the first page to the second
function getParams(){
var idx = document.URL.indexOf('?');
var params = new Array();
if (idx != -1) {
var pairs = document.URL.substring(idx+1, document.URL.length).split('&');
for (var i=0; i<pairs.length; i++){
nameVal = pairs[i].split('=');
params[nameVal[0]] = nameVal[1];
}
}
return params2;
}
params = getParams();
name = unescape(params["name"]);
document.getElementById('retro').innerHTML = name;
There are some questions around what you are trying to do here. What I have done is broken this down into 2 parts
Passing the local storage between 2 pages and accessing it.
Decoding Parameters in the URL and assigning them
Some assumptions that I made:
I have noticed some of the classes from bootstrap so i assume that you have jQuery on the page and also you may know how to use it.
Using chrome for testing this
PART 1 - Passing localstorage between windows:
First thing to note is you may be better using a cookie library (js-cookie) or creating one yourself that you can access. As localstorage may well be insecure depending on what data you want to store in there.
With that out of the way, you were on the right track, just needed to add your event listener to 'input' as i think then every keystroke the data in local storage is being updated.
Page 1
HTML
<textarea id="retro" class="form-control item"></textarea>
<button type="button" class="btn btn-primary" name="name">Send</button>
JS (I would recommend place this at the bottom of you page for quick testing)
<script type="text/javascript">
var textarea = document.getElementById('retro');
textarea.addEventListener('input',function(){
localStorage.setItem('retro', this.value);
})
</script>
In Chrome developer tools if you watch the variable 'localstorage' then you will see this change as you key in the value.
What I have done here is bound the event listener to the text area so that any 'input' the value changes, furthermore is am setting the item in the localstorage
PAGE 2
HTML
<textarea id="retro" style="height: 200px; width: 800px"></textarea>
JS
<script type="text/javascript">
var textarea = document.getElementById('retro').value = localStorage.getItem('retro');
</script>
Here using the 'getItem' method for localstorage you can then retrieve it from the storage area and output it as the value of the textarea.
Obviously is the cache or localstorage is cleared then this value will disappear.
PART 2 - Decoding Parameters in the URL and assigning them
$.urlParam = function(name){
var results = new RegExp('[\?&]' + name + '=([^]*)').exec(window.location.href);
if (results==null){
return null;
}
else{
return results[1] || 0;
}
}
This function above will get you any parameter you want form the url I found this from here. This is using jQuery.
Here is how you would use it
// example.com?param1=name¶m2=&id=6
$.urlParam('param1'); // name
$.urlParam('id'); // 6
$.urlParam('param2'); // null
Well I hope this answers your question on both parts, and helps you further, please add any comments if I have missed anything and I will be happy to update my answer
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 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.