I am trying to pass a variable to a a function that I believe calls another function (I think) but am having problems. The variable I need to use in the second function is productid but several ways thAt I have tried have not worked. either a fix in javascript or Jquery will be great!!!
This is the line that I need the variable for
var error_url = '/ProductDetails.asp?ProductCode' + productid;
this is where the variable originates from...
var productid = form.elements['ProductCode'].value;
and here is the whole js code
function addToCart2(form, button) {
var softAdd = true;
var productid = form.elements['ProductCode'].value;
var qstr;
var bttnName = button.name;
button.disabled = true;
if (form.elements['ReturnTo']) {
form.elements['ReturnTo'].value = "";
}
qstr = serialize(form, bttnName + '.x', '5', bttnName + '.y', '5');
sendAjax('POST','/ProductDetails.asp?ProductCode=' + productid + '&AjaxError=Y', qstr , retrieveProductError2 ,displayServerError,false);
button.disabled = false;
return false;
}
function retrieveProductError2(result, statusCode) {
var ele = document.getElementById('listOfErrorsSpan');
var errorIndex = result.indexOf('<carterror>');
var productIndex = result.indexOf('<ProductIndex>')
if (errorIndex > -1 && productIndex == -1) {
var error_url = '/ProductDetails.asp?ProductCode' + productid;
window.location = error_url;
}
if (errorIndex != -1) {
//ele.innerHTML = result.slice(errorIndex + 11, result.indexOf('</carterror>'));
}
else {
ele.innerHTML = "";
if (productIndex == -1) {
sendAjax('GET','/AjaxCart.asp?GetIndex=True', '', showCart, null, false);
}
else {
productIndex = result.slice(productIndex + 14, result.indexOf('</ProductIndex>'));
sendAjax('GET','/AjaxCart.asp?Index=' + productIndex, '', showCart, null, false);
}
}
}
The easiest way is to just move your variable declaration outside of your method. So change the declaration of product id outside your addToCart2 method. So outside of that method you do this:
var product_id;
Then inside your method remove var from product_id and it will just be an assignment and not declaration.
Where you pass in retrieveProductError2 as your error callback for the sendAjax call, you could instead pass in:
function(result, statusCode) { retreiveProductError2(result, statusCode, productId);}
Then change the definition of your retreiveProductError2 function to accept the additional parameter.
Related
This question already has answers here:
jQuery dot in ID selector? [duplicate]
(6 answers)
Closed 2 years ago.
I'm working on a legacy web app, that's using JQuery.
There's a place where we're trying to save all of the form data to local storage, before we redirect to a different page, so that we can restore it when we return.
This pattern is working on a number of pages:
$(document).ready(function () {
var searchForm = $('form.full-investigation');
var searchFormElements = searchForm.find(':input');
var saveSearchElements = function saveSearchElements() {
var saveData = [];
searchFormElements.each(function(index, element) {
var item = $(element);
var name = element.name;
var value = item.val();
var type = element.type;
var add = true;
if (type === "checkbox") {
value = element.checked;
} else if (type === "radio") {
if (!element.checked) {
add = false;
}
}
if (add) {
saveData.push({ name: name, value: value });
}
});
var serialized = JSON.stringify(saveData);
sessionStorage.setItem('FullInvestigation_criteria', serialized);
};
var loadSearchElements = function loadSearchElements(serializedForm) {
var foundOne = false;
if (serializedForm) {
var saveData = JSON.parse(serializedForm);
for (var i = 0; i < saveData.length; i++) {
var key = saveData[i].name;
var value = saveData[i].value;
try {
var element = searchForm.find(':input[name=' + key + ']');
if (element.length > 1) {
for (var j = 0; j < element.length; j++) {
var each = element[j];
var type = each.type;
if (type === 'radio' && each.value === value) {
each.checked = true;
foundOne = true;
}
}
} else {
element.val(value);
if (value)
foundOne = true;
}
} catch (e) {
var msg = e;
}
}
}
return foundOne;
};
$("#redirectbutton").on('click',
function(event) {
try {
saveSearchElements();
} catch (e) {
}
});
var fullInvestigation_criteria = sessionStorage.getItem('FullInvestigation_criteria');
loadSearchElements(fullInvesigation_criteria);
sessionStorage.setItem('FullInvesigation_criteria', '{}');
});
As I said, this is working on a number of pages.
But when I try to use it on a different page, where it had not been used before, I'm getting syntax errors. The problem is that on this new page, saveSearchElements() encounters :input elements with dotted names. E.g., ticketAndMarking.actualnearinter. So we're saving name/value pair with a key of "ticketAndMarking.actualnearinter"
So when we process that key in
And then when we call loadSearchElements, and it processes that key, the line:
var element = searchForm.find(':input[name=' + key + ']');
throws an exception with the message:
Syntax error, unrecognized expression: :input[name=ticketAndMarking.actualnearinter]
I was asking this question for the group, but found the answer before I posted.
So here it is, in case anyone else runs into something similar:
jQuery dot in ID selector?
Having a period in an element name is perfectly acceptable. But JQuery selector syntax requires that they be escaped.
The fix in the code above is simple:
for (var i = 0; i < saveData.length; i++) {
var key = saveData[i].name.replace(".", "\\.");
var value = saveData[i].value;
I want to have 2 buttons. Button A when clicked appends to Array A. Button B > Array B.
var names = ['Hannah', 'Lucy', 'Brenda', 'Lauren', 'Mary'];
<button id="likebutton" type="button">Like</button>
<button id="dislikebutton" type="button">Dislike</button>
function likeOrDislike(){
var off = true;
document.getElementById('likeButton').onClick = function(){
var off = false;
}
document.getElementById('dislikeButton').onClick = function(){
var off = true;
}
if(off = false) {
liked.push(names[0])
names.splice(0, 1)
}
else if (off = true) {
disliked.push(names[0])
names.splice(0, 1)
}
};
Then I call the function in this while loop:
while(names.length > 0){
document.getElementById('demo').innerHTML = names[0];
likeOrDislike()
};
Im sure there is a better way to do this then that horrible off variable.
I am getting this error at the moment
tinder.html:25 Uncaught TypeError: Cannot set property 'onClick' of null
Use .addEventListener('click', callback) or .onclick instead of .onClick
To compare values use double == or triple equals ===
Don't use while in such context. Function will be looping all the time!
Read more about Javascript, for example on w3schools
I've created working jsFiddle for you.
Here is the code:
var names = ['Hannah', 'Lucy', 'Brenda', 'Lauren', 'Mary'],
liked = [],
disliked = [];
showName();
document.getElementById('likeButton').onclick = like;
document.getElementById('dislikeButton').onclick = dislike;
function showName(){
var name = names[0];
if(!name){
name = "The End";
}
document.getElementById('demo').innerHTML = name;
}
function like(){
liked.push(names[0]);
names.splice(0, 1);
showName();
}
function dislike(){
disliked.push(names[0]);
names.splice(0, 1);
showName();
}
I'm trying to repurpose a "legacy function" to pass a function with parameters into another function and get called. I've seen bits and pieces of what I'm looking for, but my arguments keep getting passed as a single string. This is the calling code - the 4th parameter (starts with '_delRideNew') is what I need to call.
MODAL.show("Confirm", "Are you sure you want to delete this ride?","Yes","_delRideNew('" + id + "','" + day + "','" + attuid + "')","No","MODAL.hide();")
Here is the MODAL.show code (using easyui):
MODAL.show = function(title, msg, okbtn, okcallback, canbtn, cancallback) {
if(arguments.length > 2) {
$.messager.defaults.ok = okbtn;
$.messager.defaults.cancel = canbtn;
}
else {
$.messager.defaults.ok = "OK";
$.messager.defaults.cancel = "Cancel";
}
if(arguments.length === 6) {
var me = $.messager.confirm(title, msg, function(r) {
if(r) {
//parse out function and args
var pos = okcallback.indexOf("(");
var func = okcallback.substring(0,pos);
var argss = okcallback.substring(pos,okcallback.length);
argss = argss.replace("(", "");
argss = argss.replace(")", "");
var argArray = argss.split(",");
window[func](argArray);
}
else {
cancallback;
}
});
me.window('move',{
left:400,
top:document.body.scrollTop+document.documentElement.scrollTop+200
});
}
else {
confirm(msg, function(r) {
if(r) {
return true;
}
else {
return false;
}
});
}
}
The problem is when the window[func] gets called it passes the array as a single string here:
function _delRideNew(id,day,attuid){
alert(id); //shows all 3 params as a string
var txtURL = 'delRide.cfm?tech_attuid=' + attuid + '&ride_date=#getParam("month")#/' + day + "/#getParam("year")#";
SYS.loadScript(txtURL);
status = txtURL;
}
It's very much possible that I'm doing this completely wrong, but any help would be, well..helpful.
I went through few link, but that didnt help me. I have to restrict duplicate titles in json array. What is way to do here??
function submitForm(){
var titleInput=document.getElementById('titleName').value;
var messageInput=document.getElementById('titleDesc').value;
var oldItems = JSON.parse(localStorage.getItem('itemsArray')) || [];
var newItem = {
"title":titleInput ,
"desc": messageInput
};
if(!(titleInput=="" || messageInput=="")){
oldItems.push(newItem);
}
}
Try this:
if (!(titleInput == "" || messageInput == "")) {
var repeated = false;
for (var i = 0; i < oldItems.length; i++) {
if (oldItems[i].titleInput == titleInput) {
repeated = true;
break;
}
}
if (repeated == false) {
oldItems.push(newItem);
}
}
You could simply check wheter the item is there before adding it.
var alreadyExists = oldItems.some(function (item) { return item.title == titleInput; });
if(!(titleInput=="" || messageInput=="") && !alreadyExists) {
oldItems.push(newItem);
}
Then perhaps you should make the concept more explicit by encapsulating that logic within an ItemStore or something similar.
function ItemStore(items) {
this._items = [];
this._titleMap = {};
this.addAll(items || []);
}
ItemStore.prototype = {
constructor: ItemStore,
hasItemTitled: function (title) {
return !!this._titleMap[title];
},
add: function (item) {
var title = item.title;
if (this.hasItemTitled(title)) throw new Error("the store already contains an item titled '" + title + "'");
this._titleMap[title] = true;
this._items.push(item);
},
addAll: function (items) {
items.forEach(this.add.bind(this));
},
items: function () { return this._items.slice(); }
//other useful methods such as itemAt, remove...
};
Then your code becomes as simple as...
var titleInput=document.getElementById('titleName').value;
var messageInput=document.getElementById('titleDesc').value;
var oldItems = new ItemStore(JSON.parse(localStorage.getItem('itemsArray')) || []);
var newItem = {
"title":titleInput ,
"desc": messageInput
};
var shouldAddItem = titleInput != "" && messageInput !="" && !oldItems.hasItemTitled(newItem.title);
if (shouldAddItem) oldItems.add(newItem);
Now obviously, your function is still doing too much since it:
knows how to retrieve and create a new item from the user's input
knows how to rehydrate the item store
knows what to check to validate if an item is valid and should be added or not
You should be reading about the Single Responsability Principle, which isin't only applicable in OO.
After 2 weeks of hard work on my first, simple site/database I'm stuck. Friend of mine helped me on adding jquery, but now it works only in Mozilla, and he dont have idea why. I dont know java at all (and barely php). Can you take a look?
Chrome console point an error at
Uncaught SyntaxError: Unexpected token =
at line 49 which is
self.dataAdapter = function(id = 0, imie = '', nazwisko = '', kredyt = 0)
Do you have any idea what is the most compatible syntax?
The whole script:
$(document).ready(function()
{
sui = new swiezakUI();
sui.getData();
});
function swiezakUI()
{
var self = this;
self.scriptURL = "/data.php";
self.send = function(key, stuff)
{
var post = {};
post[key] = JSON.stringify(stuff);
$.ajax({
type: "POST",
url: self.scriptURL,
data: post,
contentType: "application/x-www-form-urlencoded",
dataType: "json",
success: function(data)
{
self.getData();
self.cleanForm();
},
failure: function(errMsg)
{
alert('fail');
},
error: function(errMsg)
{
alert("Blad \n" + errMsg.responseText);
}
});
}
self.id2Id = function(id)
{
for(var i = 0; i < self.myData.length; i++)
{
if(id == self.myData[i].id)
return i;
}
}
self.dataAdapter = function(id = 0, imie = '', nazwisko = '', kredyt = 0)
{
var data = new Object();
data.id = id;
data.imie = imie;
data.nazwisko = nazwisko;
data.kredyt = kredyt;
return data;
}
self.dodajNowy = function()
{
return function()
{
var data = self.dataAdapter(null, $('#imie').val(), $('#nazwisko').val(), $('#kredyt').val().replace(/\D+/g,""));
self.send('nowy',data);
}
}
self.edytujWpis = function(id)
{
return function()
{
var data = self.dataAdapter(id, $('#imie').val(), $('#nazwisko').val(), $('#kredyt').val().replace(/\D+/g,""));
self.send('edycja',data);
}
}
self.kasujWpis = function(id)
{
return function()
{
var data = self.dataAdapter(id);
self.send('kasuj',data);
}
}
self.cleanForm = function()
{
$('#imie').val('');
$('#nazwisko').val('');
$('#kredyt').val('');
$('#bZapisz').unbind();
$('#bZapisz').click(self.dodajNowy());
}
self.editButtons = function()
{
$('.edit').click(function()
{
var did = $(this).attr('id').replace(/\D+/g,"");
id = self.id2Id(did);
$('#imie').val(self.myData[id].imie);
$('#nazwisko').val(self.myData[id].nazwisko);
$('#kredyt').val(self.myData[id].kredyt);
$('#bZapisz').unbind();
$('#bZapisz').click(self.edytujWpis(did));
});
}
self.delButtons = function()
{
$('.delete').click(function()
{
var id = $(this).attr('id').replace(/\D+/g,"");
console.log(id);
self.kasujWpis(id)();
});
}
$('#bZapisz').click(self.dodajNowy());
$('#bCzysc').click(function(){
self.cleanForm();
});
self.getData = function()
{
$('#lista').children('table').html("<tr><th>id</th><th>imie</th><th>nazwisko</th><th>kredyt</th>"+
"<th>edycja</th><th>usun</th></tr>");
$.getJSON(self.scriptURL, function(data)
{
console.log(data);
self.myData = data;
for(var i = 0; i < data.length; i++)
{
$('#lista').children('table').append(
'<tr><td>'+ data[i].id +'</td>'+
'<td>'+ data[i].imie +'</td>'+
'<td>'+ data[i].nazwisko +'</td>'+
'<td>'+ data[i].kredyt +'</td>'+
'<td><button class="edit" id="e#'+data[i].id+'">e</button></td>'+
'<td><button class="delete" id="d#'+data[i].id+'">d</button></td></tr>');
}
self.editButtons();
self.delButtons();
});
}
}
Default parameters are currently part of the ES6 draft. This feature is not part of the most recent final ECMAScript standard (5.1), hence browser support is currently minimal. As of this writing, only Firefox (experimentally) implements default parameters.
There are many ways to simulate default parameters. An alternative to ES6's default parameters would be comparing arg === undefined to set the default value for it:
//if the kredyt argument has not been passed or is undefined
if (kredyt === undefined) {
kredyt = 0;
}
When a function is called passing less arguments than its parameters count, the parameters without corresponding arguments are initialized to undefined.
This way, not passing a value for the argument as well as explicitly passing undefined as the argument value will use the default parameter value, the same behavior as ES6's default parameters.
So here's the complete example:
self.dataAdapter = function(id, imie, nazwisko, kredyt)
{
//default parameters
if (id === undefined) {
id = 0;
}
if (imie === undefined) {
imie = '';
}
if (nazwisko === undefined) {
nazwisko = '';
}
if (kredyt === undefined) {
kredyt = 0;
}
//function code
var data = new Object();
data.id = id;
data.imie = imie;
data.nazwisko = nazwisko;
data.kredyt = kredyt;
return data;
}
Another common approach is comparing arg == null, which has the same effect but also accepts passing null to use the default parameter value:
//if kredyt is null, undefined or not passed
if (kredyt == null) {
kredyt = 0;
}
This works because == does type coercion, and null coerces to, and only to, undefined (ES5#11.9.3).
Yet another common approach is to use the || as the "default operator" (see related question):
kredyt = kredyt || 0; //in the beginning of the function
//...
data.kredyt = kredyt;
Or if the parameter is used only in a single place, it is possible to inline it as well:
data.kredyt = kredyt || 0;
The benefit is basically shorter code, but note that it will use the default parameter value not only when the argument is undefined, but also null, false, 0, empty string or NaN. Hence this is not a viable approach when one of these values is an acceptable parameter value different from its default parameter value.
Lastly, for use cases that need to differentiate a null/undefined value from a not passed argument (which is rare and not the case here), it's possible to check the arguments object's length property:
if (arguments.length < 4) {
kredyt = 0;
}