I am a coding beginner and I am building a store. My problem is that I have a product in different fabrics. Now I can only select one fabric type and the other is disabled and I can not select no matter what I do. Perfect would be if I select the fabric type, the associated products are displayed.
That what i mean
/*============================================================================
Dynamic variant availability
- To disable, set dynamicVariantsEnable to false in theme.liquid
==============================================================================*/
setCurrentVariantAvailability: function(variant) {
var valuesToEnable = {
option1: [],
option2: [],
option3: []
};
// Disable all options to start
this.disableVariantGroup($(selectors.formContainer, this.$container).find('.variant-input-wrap'));
// Combine all available variants
var availableVariants = this.variantsObject.filter(function(el) {
if (variant.id === el.id) {
return false;
}
// Option 1
if (variant.option2 === el.option2 && variant.option3 === el.option3) {
return true;
}
// Option 2
if (variant.option1 === el.option1 && variant.option3 === el.option3) {
return true;
}
// Option 3
if (variant.option1 === el.option1 && variant.option2 === el.option2) {
return true;
}
});
// IE11 can't handle shortform of {variant} so extra step is needed
var variantObject = {
variant: variant
};
availableVariants = Object.assign({}, variantObject, availableVariants);
// Loop through each available variant to gather variant values
for (var property in availableVariants) {
if (availableVariants.hasOwnProperty(property)) {
var item = availableVariants[property];
var option1 = item.option1;
var option2 = item.option2;
var option3 = item.option3;
if (option1) {
if (valuesToEnable.option1.indexOf(option1) === -1) {
valuesToEnable.option1.push(option1);
}
}
if (option2) {
if (valuesToEnable.option2.indexOf(option2) === -1) {
valuesToEnable.option2.push(option2);
}
}
if (option3) {
if (valuesToEnable.option3.indexOf(option3) === -1) {
valuesToEnable.option3.push(option3);
}
}
}
}
// Have values to enable, separated by option index
if (valuesToEnable.option1.length) {
this.enableVariantOptionByValue(valuesToEnable.option1, 'option1');
}
if (valuesToEnable.option2.length) {
this.enableVariantOptionByValue(valuesToEnable.option2, 'option2');
}
if (valuesToEnable.option3.length) {
this.enableVariantOptionByValue(valuesToEnable.option3, 'option3');
}
},
updateVariantAvailability: function(evt, value, index) {
if (value && index) {
var newVal = value;
var optionIndex = index;
} else {
var $el = $(evt.currentTarget);
var newVal = $el.val() ? $el.val() : evt.currentTarget.value;
var optionIndex = $el.data('index');
}
var variants = this.variantsObject.filter(function(el) {
return el[optionIndex] === newVal;
});
// Disable all buttons/dropdown options that aren't the current index
$(selectors.formContainer, this.$container).find('.variant-input-wrap').each(function(index, el) {
var $group = $(el);
var currentOptionIndex = $group.data('index');
if (currentOptionIndex !== optionIndex) {
// Disable all options as a starting point
this.disableVariantGroup($group);
// Loop through legit available options and enable
for (var i = 0; i < variants.length; i++) {
this.enableVariantOption($group, variants[i][currentOptionIndex]);
}
}
}.bind(this));
},
disableVariantGroup: function($group) {
if (this.settings.variantType === 'dropdown') {
$group.find('option').prop('disabled', true)
} else {
$group.find('input').prop('disabled', true);
$group.find('label').toggleClass('disabled', true);
}
},
enableVariantOptionByValue: function(array, index) {
var $group = $(selectors.formContainer, this.$container).find('.variant-input-wrap[data-index="'+ index +'"]');
for (var i = 0; i < array.length; i++) {
this.enableVariantOption($group, array[i]);
}
},
enableVariantOption: function($group, value) {
// Selecting by value so escape it
value = value.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g,'\\$1');
if (this.settings.variantType === 'dropdown') {
$group.find('option[value="'+ value +'"]').prop('disabled', false);
} else {
var $buttonGroup = $group.find('.variant-input[data-value="'+ value +'"]');
$buttonGroup.find('input').prop('disabled', false);
$buttonGroup.find('label').toggleClass('disabled', false);
}
},
Have already tried various things, but not come to the desired result, even disabling the function ensures that everything is displayed and also clickable.
I hope you can help me.
Best Regards
The code below only output the last result, I don't get it. I check if the updateDate item contains 2020-05 both items does and I get only the last one. The loop is not looping :)
const briefing = [
{
"updateDate": "2020-05-05T00:00:00.0Z",
},
{
"updateDate": "2020-05-06T00:00:00.0Z",
},
{
"updateDate": "2020-05-13T00:00:00.0Z",
}
];
let date = new Date();
var formattedYearMonth = date.getFullYear() + '-' + ('0' + (date.getMonth()+1)).slice(-2) + '-';
for (var i = 0; i < briefing.length; i++) {
var jsonDate = briefing[i].updateDate;
if (jsonDate.includes(formattedYearMonth)) {
var response = JSON.stringify(briefing[i]);
}
}return response;
}
for (var i = 0; i < briefing.length; i++) {
var jsonDate = briefing[i].updateDate;
if (jsonDate.includes(formattedYearMonth)) {
var response = JSON.stringify(briefing[i]); // <==== THIS IS WHERE YOUR PROBLEM LIES
}
}return response;
The loop is actually looping :). But for every run of the loop, you are resetting the value of response.
--EDITED--
For the response to be an array, you need to modify your code as
let response = [];
for (var i = 0; i < briefing.length; i++) {
var jsonDate = briefing[i].updateDate;
if (jsonDate.includes(formattedYearMonth)) {
response.push(JSON.stringify(briefing[i]));
}
}
return response;
I am attempting to disable or enable my chrome extension based on the matches of the content scripts, but I think there is a better way. Below is my code. Seems like what I am attempting to accomplish could be achieved by chrome.declarativeContent.onPageChanged but that does not seem to fire consistently.
const IsMatch = (tab, matches) => {
if (tab ==undefined && tab == null && tab.url == undefined){
return false;
}
for(var ctr = 0; ctr < matches.length ; ctr ++){
var match = matches[ctr].substring(0, matches[ctr].length - 1);
if (tab.url.startsWith(match) ) {
return true;
}
}
return false;
}
const updateIcon = tabId => {
chrome.browserAction.disable();
chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
var contentScripts = chrome.runtime.getManifest().content_scripts;
for(var i = 0; i < contentScripts.length ; i ++){
var contentScript = contentScripts[i];
if ( IsMatch(tabs[0], contentScript.matches) ) {
chrome.browserAction.enable();
console.log('chrome.tabs.query');
console.log(tabs[0]);
return;
}
}
});
};
chrome.tabs.onUpdated.addListener(updateIcon);
After the changes recommended by #wOxxOm I am now in a race condition here is the updated code
browser.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.message === 'enableIcon') {
console.log(sender.tab.id + ' ' + request.message);
chrome.browserAction.setIcon({tabId: sender.tab.id, path: 'icon-16.png'});
browser.browserAction.enable();
}
return true;
});
browser.tabs.onUpdated.addListener(function(tabId) {
console.log(tabId + ' disableIcon');
chrome.browserAction.setIcon({tabId: tabId, path: 'icon-16-Disabled.png'});
chrome.browserAction.disable();
});
Here is the ouput:
- 6: backgroundIcon.js:31 39 disableIcon
- 1: backgroundIcon.js:22 39 enableIcon
- 2: backgroundIcon.js:31 39 disableIcon
I need to call some methods using OOP way e.g. this.method() but i get some errors, this my BingoCard.js help please.
var _ = require('underscore');
// ------------------------------------ ---------
// Constructor
// ---------------------------------------------
function BingoCard() {
if(false === (this instanceof BingoCard)) {
return new BingoCard();
}
this.firstRowSchema = [];
this.secondRowSchema = [];
this.thirdRowSchema = [];
this.firstRow = [];
this.secondRow = [];
this.thirdRow = [];
this.patterns = [
{
"1" : ['x','0','x','0','x','0','x','x','0'],
"2" : ['0','x','0','x','0','x','0','x','x'],
"3" : ['x','0','x','0','x','0','x','0','x']
},
{
"1" : ['x','x','0','x','0','x','0','x','0'],
"2" : ['0','x','x','0','x','0','x','0','x'],
"3" : ['x','0','x','x','0','x','0','x','0']
}
];
this.columns = {
"1": [1,2,3,4,5,6,7,8,9],
"2": [10,11,12,13,14,15,16,17,18,19],
"3": [20,21,22,23,24,25,26,27,28,29],
"4": [30,31,32,33,34,35,36,37,38,39],
"5": [40,41,42,43,44,45,46,47,48,49],
"6": [50,51,52,53,54,55,56,57,58,59],
"7": [60,61,62,63,64,65,66,67,68,69],
"8": [70,71,72,73,74,75,76,77,78,79],
"9": [80,81,82,83,84,85,86,87,88,89,90]
};
// Use Underscore to bind all of our methods
// to the proper context
_.bindAll(this);
}
// ---------------------------------------------
// Methods
// ---------------------------------------------
BingoCard.prototype = {
resetSchemas: function () {
this.firstRowSchema = [];
this.secondRowSchema = [];
this.thirdRowSchema = [];
},
generateRows: function () {
this.cardID = _.random(8888, 999999999); // generate a Card ID.
var pattern = _.shuffle(this.patterns);
this.firstRow = pattern[0][1];
this.secondRow = pattern[0][2];
this.thirdRow = pattern[0][3];
},
createColNumber: function (col,equalNumbers) {
console.log(this.patterns);
var colNumber = this.getColNumber(col);
if(typeof equalNumbers !== 'undefined' && equalNumbers.length > 0){
equalNumbers.forEach(function(val,key){
while(colNumber == val){
colNumber = this.getColNumber(col);
}
});
}
return colNumber;
},
getColNumber: function () {
var items = _.shuffle(this.columns[col]);
return items[0];
},
generateFirstRow: function () {
var col = 0;
this.firstRow.forEach(function(val,key){
col++;
if(val == 'x'){
this.firstRowSchema[key] = this.createColNumber(col);
} else {
this.firstRowSchema[key] = 0;
}
});
return this.firstRowSchema;
}
};
// ---------------------------------------------
// Export
// ---------------------------------------------
module.exports = BingoCard;
I call the bingocard class in app.js and this is my app.js contents.
var BingoCard = require('./bingocard');
var bingocard = new BingoCard();
bingocard.generateRows();
console.log(bingocard.generateFirstRow());
When in run "node app" from console i get this error:
TypeError: Object #<Object> has no method 'createColNumber'
at /var/www/bingo/bingocard.js:10:48
but createColNumber method defined .. :(?
On the fourth row in the code below, this is not referring to the prototype. this is pointing to something else.
this.firstRow.forEach(function(val,key){
col++;
if(val == 'x'){
this.firstRowSchema[key] = this.createColNumber(col);
} else {
this.firstRowSchema[key] = 0;
}
});
You can solve this by switching out this with self. and assign this to self in the beginning of the method definition. Like this:
generateFirstRow: function () {
var col = 0,
self = this;
this.firstRow.forEach(function(val,key){
col++;
if(val == 'x'){
self.firstRowSchema[key] = self.createColNumber(col);
} else {
self.firstRowSchema[key] = 0;
}
});
return this.firstRowSchema;
}
I would like to start using Dynatree on my page, however I will probably need searching my tree by name. Do you know maybe how to do this?
I needed to have not only matching nodes, but also the whole paths to these nodes. I wrote this functionality and it works for me.
Modifications for library:
var clear = true;
DynaTreeNode.prototype.search = function(pattern){
if(pattern.length < 1 && !clear){
clear = true;
this.visit(function(node){
node.expand(true);
node.li.hidden = false;
node.expand(false);
});
} else if (pattern.length >= 1) {
clear = false;
this.visit(function(node){
node.expand(true);
node.li.hidden = false;
});
for (var i = 0; i < this.childList.length; i++){
var hide = {hide: false};
this.childList[i]._searchNode(pattern, hide);
}
}
},
DynaTreeNode.prototype._searchNode = function(pattern, hide){
if (this.childList){
// parent node
var hideNode = true;
for(var i = 0; i < this.childList.length; i++){
var hideChild = {hide: false};
this.childList[i]._searchNode(pattern, hideChild);
hideNode = hideNode && hideChild.hide;
}
if(hideNode && !this._isRightWithPattern(pattern)){
this._hideNode();
hide.hide = true;
} else {
hide.hide = false;
}
} else {
// leaf
if (!this._isRightWithPattern(pattern)){
this._hideNode();
hide.hide = true;
} else {
hide.hide = false;
}
}
},
DynaTreeNode.prototype._isRightWithPattern = function(pattern){
if((this.data.title.toLowerCase()).indexOf(pattern.toLowerCase()) >= 0){
return true;
}
return false;
},
DynaTreeNode.prototype._hideNode = function(){
if(this.li) {
this.li.hidden = true;
}
}
Use:
$("tree").dynatree("getRoot").search(pattern);
There is currently no search function, but you could use something like this (not tested)
var match = null;
tree.visit(function(node){
if(node.data.title === "foo"){
match = node;
return false; // stop traversal (if we are only interested in first match)
}
});
alert("Found " + match);
I've done it this way
<style>
span.occurance a.dynatree-title{background-color:#3AFF22;}
</style>
DynaTreeNode.prototype.find = function (needle) {
needle = (needle || '');
if (needle.length >= 1) {
var occurs = [];
this.visit(function (node) {
$(node.span).removeClass('occurance'); //remove pervious findings
if (node.data.title.indexOf(needle) != -1) {
occurs.push(node);
node._expandPath();
}
});
for (indx in occurs) { // mark findings
$(occurs[indx].span).addClass('occurance');
}
} else {
$('span.dynatree-node.occurance').removeClass('occurance');
}
},
DynaTreeNode.prototype._expandPath = function () {
var path = [],
node = this;
while (node = node.getParent()) {
path.push(node);
}
for (indx in path) {
path[indx].expand(true)
}
}
usage:
[your selector].dynatree("getRoot").find('needle');
Thanks to #mar10 i made a small, simple function to search a node with title:
// If searchFrom is null, root is used
function seachFolderNodeWithName(name, searchFrom) {
if (name == null) {
return undefined;
}
if (searchFrom == null) {
searchFrom = jQuery('#tree').dynatree("getRoot");
}
var match = undefined;
searchFrom.visit(function (node) {
if (node.data.title === name) {
match = node;
return false; // Break if found
}
});
return match;
};