Working with Shopify Variants dropdown select - javascript

in my product template page i have this code:
<select name="id" id="ProductSelect-{{ section.id }}" class="product-single__variants">
I'm using a javascript snippet to hide variants based on the customers choices. I want to use one snippet file for all my products, but cannot get javascript to read the following:
var productSelect = "ProductSelect-{{ section.id }}";
how would i do this? My alternative is that i have a snippet file for each product which although possible, makes it long and arduous.
Any ideas would be appreciated.

The issue that you're running into is that {{ section.id }} is a template variable. In the rendered HTML, that part is replaced by the appropriate variable. Once your javascript runs, there will be no element on the page with double-curly-braces in any of its attributes.
There are a few ways that you might be able to get around this:
Idea 1: Store the section ID somewhere
To do this, you would need to have some place where you can associate section IDs with sections that have loaded on the page, tying that piece of data to something that your snippet already knows about when it runs.
If, say, your snippet knows the product handle of whatever product is being changed, you could add something like this inside the form:
<script>
// If our lookup object already exists, do nothing. Otherwise, initialize it as an empty object
window.section_lookup = window.section_lookup || {};
//Now save the section ID using the product's handle
//Using the json filter when we print Liquid variables to Javascript ensures that the resulting value is always Javascript-legal.
section_lookup[{{ product.handle | json}}] = {{ section.id | json }};
</script>
Now, in your lookup code, you can use:
// Assuming that you have a variable called product_handle already
var productSelect = "ProductSelect-" + section_lookup[product_handle];
Which will give you the specific ID that you're looking for.
Idea 2: Use the power of the form object
Is your code snippet running in some context where you know something about any of the elements that contain the select element you want? For example, do you already know the form or the product-area wrapper?
If you have the form that contains your select box, you're golden. Every form knows the names of all of the form-fields contained inside it. Since the field's name is id, getting to the right select box from the form object is as easy as:
// Assuming you have a variable named form representing the correct form, access the form field with the name 'id'
var idField = form['id'];
NOTE: If your form is jQuery-selected, you probably won't have that ability. Fortunately, if you're stuck with a jQuery-wrapped object you can easily un-wrap it like so:
// Assuming somebody gave you a variable named $form that they jQuery-selected....
var form = $form[0];
var idField = form['id'];
If you don't have the form but you do have quick access to any other input inside the form, you're also in luck - Every form element (ie: inputs, selects, textareas, fieldsets...) also knows what form it belongs to.
// Assuming that there is a variable named target which is a form element contained in the same form as the ID field that we want:
var form = target.form;
var idField = form['id'];
Idea 3: Use some other wrapping element to constrain your lookup
If you know anything about some wrapping element that contains the select box that you want and doesn't include the select box that you don't want, you can constrain your query-selector to only look inside the wrapper. That way, you'll only find the element that you need.
If you're using plain ol' "vanilla" Javascript:
//Assuming we have a variable named product_wrapper
var idField = product_wrapper.querySelector('[name="id"]');
Or if you prefer jQuery:
//Still assuming that we have a variable named product_wrapper
var idField = jQuery('[name="id"]', product_wrapper);
Hopefully you can find success with at least one of these methods. Good luck!

Related

Javascript Dynamic variable names not working

I have a table in a form with a list of products where there is an input for each (let's call it 'pc'). Each input is named as 'pc' and product id with an id as the same. IE: 'pc100', 'pc101', etc. Each input has an onkeyup event to call a function to populate a price where I pass the product id (onkeyup='myfunction(100) The function receives the id but I cannot configure the javascript to that id. I will have the rest of the code as long as I can get the dynamic variable name. The internet is full of all kinds of things like eval() and window[] and I have tried every possible combination I can think of/find. I know it's possible to get this to work. So...how can I get this alert to work?
Most the results I will give me 'pc100' when I need 'Heres my test'
function myfunction(idpro) {
var pc331 = 'Heres my test';
alert( "pc" + idpro );
}
Don't use dynamic variable names. Do use look-ups in data structures:
function f(id) {
var pc = {
331: "Here's my test"
}
console.log(pc[id]);
}
Dynamic variables are a huge problem, especially from a security perspective. If you were naive and used eval someone could construct an id value that executes arbitrary JavaScript and then you have an XSS problem.

Changing object data in javascript of a Django/Heroku website

I'm wondering if it's possible for me to change the values of a data object inside my javascript. The javascript receives postmessages from an iframe and I need to be able to store that information to the correct objects, but I'm not quite sure how to do it on the HTML surface or if it's possible to do in the javascript surface.
I can call
{{ game.high_score}}
in the HTML to fetch the high_score of a certain game object, but my attempts at working out how to have my javascript send values to these objects flies right over my head.
The most recent venture I tried was simply doing
game.gameData.name = somevalue;
in the javascript, but this doesn't seem to change the global value for this data object value (the change is not seen outside of the javascript).
Are there any solid ways of handling this inside/outside of javascript in Django/Heroku environment?
Edit:
I'm not having trouble at grabbing data from POST: The question might as well be as to how I can change a game object's value when the value I want to change it to stems from javascript.
The game class object I have looks something like this:
class GameInstanceDto:
def __init__(self, base: GameIdentityDto, high_score: int, state: str):
self.base = base,
self.high_score = high_score,
self.state = state
if I can call the game specific highscore in the HTML with
{{ game.high_score }}
and I want to alter the value of it in javascript, I personally tried to go with
game.high_score = "2500";
just to see if the value of the high_score would change, but I didn't see it change at all.
I'm not sure if you want to POST the changes back to your model or not so let's take it 1 step at a time.
Alter {{ game.high_score }} with JavaScript
<div id="high_score">{{ game.high_score }}</div>
<script>
var high_score = document.getElementByID('high_score');
high_score.innerHTML = 2500;
</script>
Now, it you actually want to send in back as a POST, make element high_score an input field within a form

Multiple search by ID. Search not knowing full ID. Sapui5

I was wondering if there was any option to search an element by its id but not knowing the full ID, only part of it. So I could find an element without knowing its full ID or find multiple elements with similar IDs.
For example if I knew I had 3 objects with the followings ID:
"objectID1" "objectID2" and "objectID3".
Could I something like:
getElementByID("objectID*")
I have tried it in JavaScript using: input[id*='PART_OF_ID_I_KNOW']
But it returns an HTML object and I need it for SAPUI5.
Could I use something like:
var myControl = sap.ui.getCore().byId('myId');
But not having to match the full ID (myID)? Thanks.
Though I would not recommend this but it's possible in a way as you describe it.You could look for elements with similar ID with jQuery, get the element's ID and pass it to sap.ui.getCore().byId();
var aElements = $("div[id*='PART_OF_ID_YOU_KNOW']");
//Lets say the first element returned is the one belonging to your control
var oControl = sap.ui.getCore().byId(aElements[0].id); //If the element is a SAPUI5 control, you should get it.
Why do you need to do this? Is it because you want to access controls (with prefixed IDs) inside your views and fragments? Did you give an ID of "myControl" to the control, but sap.ui.getCore().byId("myControl") doesn't work as the framework added a prefix to it?
If yes, the only reliable way to get a reference to your control is by using the framework provided methods in MVC views and controllers and in fragments.
If you have a control called "myButton" in your view, do this.byId("myButton") or this.getView().byId("myButton") from the controller to get a reference to your control.
If you have a control called "myButton" in a fragment that you embedded in your view via sap.ui.xmlfragment("", "myFragment.fragment.xml"), then use sap.ui.core.Fragment.byId("<prefix>", "myButton") to access it.
Whatever you do, don't make assumptions on how the framework creates these prefixed IDs. These are not documented and can change.
when you use `var myControl = sap.ui.getCore().byId('myId');`
it won't work.It is because when you try to get control by sap.ui.getCore() sapui5 automatically concat extra string to Your id egsap.ui.getCore().byId('xml0--myId') and if you have provided viewId in manifest then while rendering control it uses that. eg
sap.ui.getCore().byId('yourManifiestId--myId')

Is it possible to get the xml_id from JS code in Odoo?

I am trying to get a specific menuitem and store it in a variable in JavaScript:
var Menus = new openerp.web.Model('ir.ui.menu');
Now, we can apply a filter to Menus to get the menuitem, for example, look for its name, but the thing is that there are a lot of menuitems with the same name. So I think that the only attribute which identifies my menuitem and differences it from the other is the XML ID.
But I do not know how to get it from JavaScript code. Is there any built function to obtain it? How can I manage my purpose?
Well, I have found a workaround. May be there is a better solution, in that case, please, post it.
In the database, there is a table named ir_model_data. This table stores the XML IDs, under the column name. The columns model and res_id indicate you the model where that XML ID record was stored and its ID. There is also a column named module, which can be used to put that before the XML ID extracted (column name), to get the module_name.xml_id notation.
For example:
I have a record from ir.ui.menu model with ID 303, and I want to get its XML ID from Javascript:
var Menus = new openerp.web.Model('ir.model.data');
Menus.query(['name']).filter(['&', ['model', '=', 'ir.ui.menu'], ['res_id', '=', 303]]).all().then(function(ir_model_datas) {
for (i in ir_model_datas) {
console.log(ir_model_datas[i].name);
}
});

Not able to access form elements when there page is called with a querystring

I have a number of webpages on which I have the following piece of Javascript
var inputs = $("body :input");
for(i=0;i<inputs.length;i++)
{
thisObj =inputs[i];// test if the class 'roll' exists
if (thisObj.getAttribute('type') == 'text')
{
params+=thisObj.id + "="+thisObj.value+"&";
}
}
If the page it is called from does not have any querystring elements tagged on to the URL (i.e. localhost/default.aspx ) it works fine and params is populated.
If however it is called from a page containing a querystring element in the url (i.e. localhost/default.aspx?ref=42) inputs is returned as an empty array and params is blank.
I know that I have probably missed something very obvious but for the life of my I cannot work out what the cause is.
Edit:
To be clearer if I simplify the code to:-
var par='';
var inputs = $("body :input");
par ="c="+inputs.length;
I get c=9 if the url does not have a GET parameter and an empty string if the url has a GET parameter
The code appears to be preparing a querystring (the variable params) by collecting data from various input fields on a page, most likely for a subsequent redirect to a dynamically generated URL containing the form data in the form of GET parameters. Note that the jQuery selector "body :input" effectively selects all elements within the entire page that can reasonably be used for user input (input, textarea, select and button, to be precise).
Thus, the code is likely intended to be used on the page where where the query string that you refer to is assebled, and not the one on which the parameters are read and put into use.

Categories