Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding difficult view model

I am trying to replace some text in an input field using JS but the view model overrides my commands each time. This is the HTML I start with:

<td class="new-variants-table__cell" define="{ editVariantPrice: new Shopify.EditVariantPrice(this) }" context="editVariantPrice" style="height: auto;">
    <input type="hidden" name="product[variants][][price]" id="product_variants__price" value="25.00" bind="price" data-dirty-trigger="true">
    <input class="mock-edit-on-hover tr js-no-dirty js-variant-price variant-table-input--numeric" bind-event-focus="onFocus(this)" bind-event-blur="onBlur(this)" bind-event-input="onInput(this)">
</td>

I run this JS:

jQuery('#product_variants__price').siblings().removeAttr('bind-event-focus');
jQuery('#product_variants__price').siblings().removeAttr('bind-event-input');
jQuery('#product_variants__price').siblings().removeAttr('bind-event-blur');
jQuery('#product_variants__price').siblings().focus()
jQuery('#product_variants__price').siblings().val("34.00");
jQuery('#product_variants__price').val("34.00");

And I'm left with the following HTML:

<td class="new-variants-table__cell" define="{ editVariantPrice: new Shopify.EditVariantPrice(this) }" context="editVariantPrice" style="height: auto;">
    <input type="hidden" name="product[variants][][price]" id="product_variants__price" value="34.00" bind="price" data-dirty-trigger="true">
    <input class="mock-edit-on-hover tr js-no-dirty js-variant-price variant-table-input--numeric">
</td>

The problem is that each time I click the input field the value is reverted to what it was when the page loaded.

I've also tried running the command in the parent td along with my value change, to simulate the editing of a variant and preventing default with no success:

jQuery('#product_variants__price').siblings().bind('input', function (e) {
    e.preventDefault();
    return false;
});
jQuery('#product_variants__price').siblings().bind('focus', function (e) {
    e.preventDefault();
    return false;
});
jQuery('#product_variants__price').siblings().focus()
jQuery('#product_variants__price').siblings().val("£34.00");
jQuery('#product_variants__price').val("£34.00");
jQuery('#product_variants__price').siblings().keydown()

Parent td function:

new Shopify.EditVariantPrice(jQuery('#product_variants__price').parent())

So how can I successfully edit this value in the inputs and also update the Shopify view model?

You can try this for yourself by going here:

https://jebus333.myshopify.com/admin/products/2521183043

login [email protected] password shop1

EDIT: I've tried to find the view model on the page but with no success. Plus, there are no network calls when editing the values in the input fields, leading me to believe the values are being pulled back from somewhere on page.

like image 507
forgetso Avatar asked Aug 27 '15 14:08

forgetso


3 Answers

Try this:

var old = Shopify.EditVariantPrice.prototype.onFocus;
Shopify.EditVariantPrice.prototype.onFocus = function(t) { 
  this.price = '50.00'; // Use the price you want here
  old.call(this, t); 
};
jQuery('#product_variants__price').siblings().triggerHandler("focus");
jQuery('#product_variants__price').siblings().triggerHandler("blur");

If it works for you, it's possible that the following will be sufficient:

Shopify.EditVariantPrice.prototype.onFocus = function(t) { 
  this.price = '50.00'; // Use the price you want here
};
like image 116
bumpy Avatar answered Nov 19 '22 20:11

bumpy


Well, there is a kind of a dirty solution...

First of all you'll need a sendkeys plugin. In fact that means you'll need to include this and this JS libraries (you can just copy-paste them in the console to test). If you don't want to use the first library (I personally find it quite big for such a small thing) you can extract only the key things out of it and use only them.

The next step is creating the function which is going to act like a real user:

function input(field, desiredValue) {
  // get the currency symbol while value is still pristine
  var currency = field.val()[0];

  // move focus to the input
  field.click().focus();

  // remove all symbols from the input. I took 10, but of course you can use value.length instead
  for (var i = 0; i < 10; i++) field.sendkeys("{backspace}");

  // send the currency key
  field.sendkeys(currency);

  // send the desired value symbol-by-symbol
  for (var i = 0; i < desiredValue.length; i++) field.sendkeys(desiredValue[i]);
}

Then you can simply call it with the value you wish to assign:

input($("#product_variants__price").next(), "123.00");

I did not really manage to fake the blur event because of lack of the time; that is why I was forced to read the currency and pass .00 as a string. Anyway you already have a way to go and a quite working solution.

like image 22
smnbbrv Avatar answered Nov 19 '22 18:11

smnbbrv


Looks like you're trying to automate editing of variant prices of products in Shopify's admin panel.

Instead of playing around with the DOM of Shopify's admin page, I'll suggest using Shopify's bulk product editor which lets you set prices of all variants in a single screen. I feel that you'll have better luck setting the variant prices using JavaScript on the bulk product editor page.

Clicking on the 'Edit Products' button as shown in the screenshot below will open the bulk product editor.

Click on 'Edit Products' to open the bulk product editor.

Also check if browser based macro recording plugins like iMacro can be of your help (you can also code macros with JS in iMacro).

like image 1
nhylated Avatar answered Nov 19 '22 20:11

nhylated