title: Jquery fancy product designer
body: <p>I am recently using <code>jquery</code> Fancy product designer and I am experiencing the following problem.
  I want to use the product price for calculation but I cannot find a way to do it.</p>
  
  <p>the code is:<br>
   //event handler when the price is changing</p>
  
  <pre><code>$('#clothing-designer').bind('priceChange', function(evt, price, currentPrice) {
      $('#thsirt-price').text(currentPrice);
  });
  </code></pre>
  
  <p>and the HTML is: </p>
  
  <pre><code>&lt;div class="col-md-3"&gt;
  PRICE &lt;span class="price badge badge-inverse"&gt;&lt;span id="thsirt-price"&gt;&lt;/span&gt; €&lt;/span&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>How do I get the price in numeric form?</p>
  
  <p>The extra code is </p>
  
  <pre><code>FancyProductDesigner.prototype.removeElement = function(element) {
  
      if(typeof element === 'string') {
          element = thisClass.getElementByTitle(element);
      }
  
      if(element.params.price != 0 &amp;&amp; !element.params.uploadZone) {
          currentPrice -= element.params.price;
          $elem.trigger('priceChange', [element.params.price, currentPrice]);
      }
  
      $contextDialog.find('.fpd-content-layers .fpd-list').children('[id="'+element.id+'"]').remove();
  
      stage.remove(element);
  
      if(element.params.hasUploadZone) {
  
          //check if upload zone contains objects
          var objects = stage.getObjects(),
              uploadZoneEmpty = true;
          for(var i=0; i &lt; objects.length; ++i) {
              var object = objects[i];
              if(object.visible &amp;&amp; object.params.replace == element.params.replace) {
                  uploadZoneEmpty = false;
                  break;
              }
          }
          var uploadZoneObject = _getUploadZone(element.params.replace);
  
          uploadZoneObject.opacity = uploadZoneEmpty ? 1 : 0;
      }
  
      /**
       * Gets fired as soon as an element has been removed.
       *
       * @event FancyProductDesigner#elementRemove
       * @param {Event} event
       * @param {fabric.Object} element - The fabric object that has been removed.
       */
      $elem.trigger('elementRemove', [element]);
      thisClass.deselectElement();
  
  };
  
  /**
   * Returns an fabric object by title.
   * @param {string} title The title of an element.
   */
  FancyProductDesigner.prototype.getElementByTitle = function(title) {
  
      var objects = stage.getObjects();
      for(var i = 0; i &lt; objects.length; ++i) {
          if(objects[i].title == title) {
              return objects[i];
              break;
          }
      }
  
  };
  
  /**
   * Sets the zoom of the stage. 1 is equal to no zoom.
   * @param {number} value The zoom value.
   */
  FancyProductDesigner.prototype.setZoom = function(value) {
  
      thisClass.deselectElement();
      var point = new fabric.Point(stage.getWidth() * 0.5, stage.getHeight() * 0.5);
      stage.zoomToPoint(point, value);
      if(value == 1) {
          thisClass.resetZoom();
      }
  
  };
  
  /**
   * Resets the zoom.
   */
  FancyProductDesigner.prototype.resetZoom = function() {
  
      thisClass.deselectElement();
      stage.zoomToPoint(new fabric.Point(0, 0), 1);
      stage.absolutePan(new fabric.Point(0, 0));
  
  };
  
  /**
   * Sets the dimensions of the stage(canvas). todo: check
   * @param {number} width The width for the stage.
   * @param {number} height The height for the stage.
   */
  FancyProductDesigner.prototype.setStageDimensions = function(width, height) {
  
      options.width = width;
      options.stageHeight = height;
  
      $elem.width(width);
      $productStage.height(height * responsiveScale);
      stage.setDimensions({width: $elem.width(), height: options.stageHeight * responsiveScale})
      .calcOffset().renderAll();
  
      _refreshDesignerSize();
  
  };
  
  /**
   * Shows a message in the snackbar.
   * @param {string} text The text for the message.
   */
  FancyProductDesigner.prototype.showMessage = function(text) {
  
      var $snackbar;
  
      if($body.children('.fpd-snackbar-internal').size() &gt; 0) {
          $snackbar = $body.children('.fpd-snackbar');
      }
      else {
          $snackbar = $body.append('&lt;div class="fpd-snackbar-internal fpd-snackbar fpd-shadow-1"&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;').children('.fpd-snackbar-internal');
      }
  
      $snackbar.removeClass('fpd-show-up').children('p').html(text).parent().addClass('fpd-show-up');
  
      setTimeout(function() {
          $snackbar.removeClass('fpd-show-up');
      }, 3000);
  
  };
  
  /**
   * Calls a specified content in the context dialog.
   * @param {string} target An unique target name. Possible values: 'layers', 'adds', 'products', 'saved-products', 'edit'.
   * @param {string} title The title for the context dialog, which appears in the head of the context dialog.
   * @param {string} [subTarget] An unique sub-target name. The 'adds' dialog has following sub-dialogs: 'facebook', 'instagram', 'designs'.
   * @param {boolean} [deselectElement] Deselects the current selected element.
   */
  FancyProductDesigner.prototype.callDialogContent = function(target, title, subTarget, deselectElement) {
  
      subTarget = typeof subTarget !== 'undefined' ? subTarget : null;
      deselectElement = typeof deselectElement !== 'undefined' ? deselectElement : true;
  
      if(deselectElement) {
          thisClass.deselectElement();
      }
  
      //hide sub contents
      $contextDialog.find('.fpd-content-sub.fpd-show').removeClass('fpd-show');
      //hide content-back button
      $contextDialog.find('.fpd-content-back').removeClass('fpd-show');
  
      //get target div
      var $target = $contextDialog.find('.fpd-dialog-content .fpd-content-'+target);
      if($target.is(':hidden')) {
          $target.siblings('div').stop().hide()
          //show requested content div
          $target.stop().fadeIn(300);
      }
  
      $contextDialog.show();
  
      //lazy load for products
      if(target == 'products' &amp;&amp; options.lazyLoad) {
          $currentLazyLoadContainer = $target;
          _refreshLazyLoad(false);
      }
  
      if(subTarget) {
  
          var $subTarget = $contextDialog.find('.fpd-content-sub[data-subContext="'+subTarget+'"]').addClass('fpd-show');
          $contextDialog.find('.fpd-content-back').data('parentTitle', $contextDialog.find('.fpd-dialog-title').text())
          .addClass('fpd-show');
  
          //lazy load for designs
          $currentLazyLoadContainer = null;
          if(subTarget == 'designs' &amp;&amp; options.lazyLoad) {
              $currentLazyLoadContainer = $subTarget;
              _refreshLazyLoad(false);
          }
  
      }
  
      _setDialogTitle(title);
  
  };
  
  /**
   * Defines the current upload zone by using the title of a visible upload zone.
   * @param {string} title The title of a visible upload zone.
   */
  FancyProductDesigner.prototype.setUploadZone = function(title) {
  
      currentUploadZone = title;
      thisClass.closeDialog();
  
  };
  
  /**
   * Closes the context dialog box
   */
  FancyProductDesigner.prototype.closeDialog = function() {
  
      $contextDialog.hide();
      $colorPicker.find('input').spectrum('hide');
      $currentLazyLoadContainer = null;
      currentUploadZone = null;
  
  };
  
  /**
   * Defines a clipping rectangle for an element.
   * @param {fabric.Object | string} element A fabric object or the title of an element.
   * @param {object} clippingRect Ob object containg x, y, width and height values to define the rectangle.
   * @example
   * yourDesigner.setClippingRect("Element Title", {x: 100, y: 200, width: 300, height: 400});
   * @version 3.0.2
   */
  FancyProductDesigner.prototype.setClippingRect = function(element, clippingRect) {
  
      //if element is string, get by title
      if(typeof element == 'string') {
          element = thisClass.getElementByTitle(element);
      }
  
      element.clippingRect = clippingRect;
      stage.renderAll();
  
  };
  
  /**
   * Sets the parameters for a specified element.
   * @param {fabric.Object | string} element A fabric object or the title of an element.
   * @param {object} parameters An object with the parameters that should be applied to the element.
   */
  FancyProductDesigner.prototype.setElementParameters = function(element, parameters) {
  
      if(element === undefined || parameters === undefined) {
          return false;
      }
  
      //if element is string, get by title
      if(typeof element == 'string') {
          element = thisClass.getElementByTitle(element);
      }
  
      //store undos
      if(productCreated) {
          var oldParameters = {};
          for (var key in parameters) {
              oldParameters[key] = element.params[key];
          }
          undos.push({element: element, parameters: oldParameters});
      }
  
      //adds the element into a upload zone
      if(currentUploadZone &amp;&amp; currentUploadZone != '') {
  
          parameters.z = -1;
  
          var uploadZoneObj = thisClass.getElementByTitle(currentUploadZone),
              bbRect = uploadZoneObj.getBoundingRect();
  
          $.extend(parameters, {
                  boundingBox: currentUploadZone,
                  scale: thisClass.getScalingByDimesions(element.getWidth(), element.getHeight(), (bbRect.width / responsiveScale)-1, (bbRect.height / responsiveScale)-1),
                  autoCenter: true,
                  removable: true,
                  zChangeable: false,
                  rotatable: uploadZoneObj.params.rotatable,
                  draggable: uploadZoneObj.params.draggable,
                  resizable: uploadZoneObj.params.resizable,
                  price: uploadZoneObj.params.price,
                  replace: currentUploadZone,
                  hasUploadZone: true
              }
          );
  
          uploadZoneObj.opacity = 0;
  
      }
  
      //check if a upload zone contains an object
      var objects = stage.getObjects();
      for(var i=0; i &lt; objects.length; ++i) {
          var object = objects[i];
          if(object.params &amp;&amp; object.params.uploadZone &amp;&amp; object.title == parameters.replace) {
              object.opacity = 0;
          }
      }
  
      //if topped, z-index can not be changed
      if(parameters.topped) {
          parameters.zChangeable = false;
      }
  
      //new element added
      if( typeof parameters.colors === 'object' ||
          parameters.removable ||
          parameters.draggable ||
          parameters.resizable ||
          parameters.rotatable ||
          parameters.zChangeable ||
          parameters.editable ||
          parameters.patternable
          || parameters.uploadZone) {
  
          element.isEditable = element.evented = true;
          element.set('selectable', true);
  
  
          if(element.viewIndex == currentViewIndex &amp;&amp; $contextDialog.find('.fpd-content-layers .fpd-list-row[id="'+element.id+'"]').size() == 0) {
              _appendLayerItem(element.id, element.title, parameters.zChangeable, parameters.removable, parameters.uploadZone, !element.evented);
          }
  
      }
  
      if(parameters.opacity !== undefined) {
          element.set('opacity', parameters.opacity);
          //needs to be called for curved text
          if(element.params.curved) {
              element.setFill(element.fill);
          }
      }
  
      //upload zones have no controls
      if(!parameters.uploadZone || options.editorMode) {
  
          if(parameters.draggable) {
              element.lockMovementX = element.lockMovementY = false;
          }
  
          if(parameters.rotatable) {
              element.lockRotation = false;
          }
  
          if(parameters.resizable) {
              element.lockScalingX = element.lockScalingY = false;
          }
  
          if((parameters.resizable || parameters.rotatable || parameters.removable)) {
              element.hasControls = true;
          }
  
      }
  
      if(parameters.originX) {
          element.setOriginX(parameters.originX);
  
      }
  
      if(parameters.originY) {
          element.setOriginY(parameters.originY);
      }
  
      if(parameters.x !== undefined) {
          element.set('left', parameters.x);
      }
  
      if(parameters.y !== undefined) {
          element.set('top', parameters.y);
      }
  
      if(parameters.scale !== undefined) {
          element.set('scaleX', parameters.scale);
          element.set('scaleY', parameters.scale);
      }
  
      if(parameters.degree !== undefined) {
          element.set('angle', parameters.degree);
      }
  
      //replace element
      if(parameters.replace &amp;&amp; parameters.replace != '' &amp;&amp; element.viewIndex === currentViewIndex) {
          var objects = stage.getObjects();
          for(var i = 0; i &lt; objects.length; ++i) {
              var object = objects[i];
              if(object.params != undefined &amp;&amp; object.clipFor == undefined &amp;&amp; object.params.replace == parameters.replace &amp;&amp; object.visible &amp;&amp; element !== object) {
                  parameters.z = _getZIndex(object);
                  parameters.x = object.params.x;
                  parameters.y = object.params.y;
                  parameters.autoCenter = false;
                  thisClass.removeElement(object);
                  break;
              }
          }
      }
  
      //center element
      if(parameters.autoCenter) {
          _doCentering(element);
      }
  
      if(parameters.flipX !== undefined) {
          element.set('flipX', parameters.flipX);
      }
  
      if(parameters.flipY !== undefined) {
          element.set('flipY', parameters.flipY);
      }
  
      if(parameters.price &amp;&amp; !parameters.uploadZone) {
          currentPrice += parameters.price;
  
          /**
           * Gets fired as soon as the price has changed.
           *
           * @event FancyProductDesigner#priceChange
           * @param {Event} event
           * @param {number} elementPrice - The price of the element.
           * @param {number} totalPrice - The total price.
           */
          $elem.trigger('priceChange', [parameters.price, currentPrice]);
      }
  
      //change element color
      if(parameters.currentColor !== undefined &amp;&amp; parameters.pattern == null) {
          _changeColor(element, parameters.currentColor);
      }
  
      //set pattern
  
      if(parameters.pattern !== undefined) {
          _setPattern(element, parameters.pattern);
      }
  
      //set filter
      if(parameters.filter) {
          element.filters = [];
          var fabricFilter = _getFabircFilter(parameters.filter);
          if(fabricFilter != null) {
              element.filters.push(fabricFilter);
          }
          element.applyFilters(function() {
              stage.renderAll();
              $body.mouseup();
          });
      }
  </code></pre>