Set default values for other options when an option is selected in Angular

Question: How do I use the selected sizes as an index to match and show the correct price and tsin associated with that size index?


Notice:

  • I am attempting to create a connection between sizes, prices, and tsin

      "Black": {
        "sizes": "X Small, Small",
        "prices": '$22.24, $24.94',
        "tsin": "111002, 111003"
      },
    

For example, if black is chosen and the size selected is index [0] (or X Small), then when ng-change occurs, the price should update to $22.24 and the tsin should be 111002


UPDATE: I have made some modifications in an attempt to reach the desired functionality but prototypical inheritance is still missing. Just aiming to demonstrate the intended effect

UPDATED JSFiddle

UPDATED 2x Received a solution from Callebe which brought me closer, yet still not fully functional

JSFiddle

I have a basic controller with some mock data fetched via $http:

var app = angular.module("app", []);

app.controller('Ctrl', function ($scope, $filter, $http) {
    //lowest price is fetched during the initial API request on production
    var lowestPrice = '$21.24';
    // exposes currentPrice to the view
    $scope.currentPrice = lowestPrice;

    // function to switch the currentPrice to the price of the selected product
    $scope.getCurrentPrice = function(idx) {
          $scope.currentPrice = idx;
    }
 //mock data simulating part of the json object response
 $scope.productData = {
  "colors_and_sizes": {
    "data": {
      "Black": {
        "prices": '$21.24, $29.94',
        "swatch_image": 'http://lorempixel.com/50/50',
        "sizes": "X Small, Small",
        "prices": '$22.24, $24.94',
        "tsin": "111002, 111003"
      },
      "Blue": {

        "swatch_image": 'http://lorempixel.com/50/51',
        "sizes": "X Small, Small",
        "prices": '$22.24, $24.94',
        "tsin": "112005, 112007"
      }
    }
  }
};

});

Notice:

  • The formatting of the incoming data needs improvement for my requirements.

The sizes, prices, and tsin are stored as strings. They are split when reaching the view:

<form ng-app="app" ng-controller="Ctrl" ng-init="item = this">
    <div class="color-pick" 
         ng-repeat="(key, val) in productData.colors_and_sizes.data track by $index">
        <input 
             type="radio" 
             name="colors" 
             hidden="true"  
             ng-model="item.myColor" 
             ng-value="key" />

        <img 
             ng-click="item.myColor = key" 
             ng-src="{{val.swatch_image}}" 
             alt="">
        {{key}} 

        <div class="size-pick" ng-show="item.myColor==key">
            <select 
                ng-model="item.mySize"

                <!--split the sizes into an array named choice -->
                <!--idx as choice could represent the index to get the key but it disrupts the value; cannot do (idx, choice) as choice for (idx, choice) in val.sizes.split(',') -->
                ng-options="choice as choice for (idx, choice) in val.sizes.split(',')">
                <option value="">Please select a size</option>

                ng-change="setCurrentPrice(val.sizes.split(',')[idx])"
            </select>
        </div>

    </div>
</form>

In the end, I aim to display 4 values on the view:

mySize: {{ item.mySize}}
myColor: {{item.myColor}}
myPrice: {{item.currentPrice}} 
myTsin: {{item.myTsin}} 

Once again, please review the old fiddle linked above

Answer №1

Here is a straightforward solution:

See the working demo here

HTML Code Snippet

<select ng-model="item.mySize" ng-change="setCurrentPrice(val.sizes.split(','),val.prices.split(','),val.tsin.split(','))" ng-options="choice as choice for (idx, choice) in val.sizes.split(',')">
     <option value="">Please select a size</option>
</select>

JavaScript Function

$scope.setCurrentPrice = function(sizes, prices, tsin) {
        var index = sizes.indexOf($scope.item.mySize);
        $scope.item.myPrice = prices[index];
        $scope.item.myTsin = tsin[index];
        $scope.item.currentPrice = prices[index];
        $scope.item.mySize = sizes[index];
    };

Answer №2

To streamline your code, you can create a controller function that takes an item as a parameter and then calculates the remaining attributes based on it.

$scope.fillItem = function(item) {
    var color = $scope.productData.colors_and_sizes.data[item.myColor];
    if(!color) return;

    var size = item.mySize,
    index = -1, i = 0,
    sizes = color.sizes.split(","),
    prices = color.prices.split(","),
    tsin = color.tsin.split(",");

    while(index == -1 && i < sizes.length) {
        if(sizes[i] == size) index = i;
        i++;
    }

    if(index >= 0) {
        item.currentPrice = prices[i];
        item.myTsin = tsin[i];
    }
}

Include this in your HTML:

<img  ng-click="item.myColor = key; fillItem(item);" 
      ng-src="{{val.swatch_image}}" 
      alt="">

<div class="size-pick" ng-show="item.myColor==key">
        <select 
            ng-model="item.mySize"
            ng-change="fillItem(item);"
            ng-options="choice as choice for (idx, choice) in val.sizes.split(',')">
            <option value="">Please select a size</option>
        </select>
    </div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

unable to scroll using jquery up and down buttons

I'm currently working on implementing scroll up and down buttons on my website, but I seem to be encountering some issues. Here is the code that I have so far... HTML: <body> <div id="middle-body">test</div> <div id="toT ...

Sluggish data-binding while using ng-repeat

I am facing an issue where I have an array of objects in the controller that is loaded when the page loads. On a socket.io event, I need to update the data inside this array. The socket.io functionality is working fine and the data changes within seconds, ...

The Express server powered by Node.js is failing to send responses back to HTTP requests initiated from a JavaScript file, despite successfully receiving and processing the requests

I am facing an issue with my setup where I have both a node-js server and an apache server running on the same machine. One of my javascript files is sending an HTTP request to the node-js server, which receives the file, reads the data, and puts it in the ...

Is IE causing issues with AJAX and document.getElementById().innerHTML?

Despite claims that I did not thoroughly research, I can assure you that I have reviewed extensively all information related to my query. Unfortunately, I have yet to find a satisfactory answer. I have implemented a basic AJAX script that is designed to lo ...

Is it possible for an onbeforeunload event to take too long to complete? What could I be overlooking?

This issue appears to be quite common, yet I haven't come across any identical cases or solutions that actually work. Therefore, I am adding my voice to the chorus. The code snippet I have handles the scenario where: window.onbeforeunload = function ...

Utilizing Google Maps on a jQuery Mobile website

I need to make a change on my jQuery mobile site that currently uses onload="initialize()" in the body tag to display a Google map. I want to find a way to show the map without needing onload="initialize()". Can someone help me figure out what modification ...

Ensure the header remains fixed when scrolling in an HTML page with Bootstrap

I created the following code. However, when I scroll down the table, the header disappears from view. I would like the header to always remain at the top, even when scrolling. Despite searching Google multiple times and trying various solutions, I have no ...

Deactivate button after a set period of time

Using angularjs, I have a button to create tickets that works with an http request to call a PHP web service. The problem is that the http request has a delay of x seconds, allowing users to click multiple times during this delay resulting in multiple ti ...

Attempting to access a PHP object using a dollar sign as the node name resulted in a syntax error, specifically a T_CONSTANT_ENCAPSED_STRING error

As I delve into this problem, I have identified the specific issue I am facing. Unfortunately, the suggested solution does not resolve my problem. Access a PHP-object with dollar-sign as node name This is the relevant PHP code snippet: $user = 'off ...

Equally distributing the space while adjusting the size of the browser window

When adjusting the size of the browser window, I noticed that the space after the element is reduced. I would like to decrease the space equally on both the left and right sides, similar to how it is done on Facebook. Below is the code I have: CSS: body ...

Guide to generating dynamic multiple fields in AngularJS

I have an AngularJS app where I am adding multiple dynamic fields within a form. Here is how I have tried to do it: The JavaScript file looks like this: $scope.commonData = [{ 'a': '', 'b': '', }]; $scope. ...

Building CoffeeScript with AngularJS sans Yeoman

As a learning exercise, I am attempting to convert a small AngularJS app from JavaScript to CoffeeScript. The CoffeeScript file, appcoffee.coffee, now includes: 'use strict' UsrAdmApp = angular.module 'UsrAdmApp', ['ngAnimate&ap ...

Using Rails to render various js templates based on different AJAX requests

My Rails app includes a Movies#index page where I send AJAX requests in two scenarios: When I am loading more @movies When I am filtering @movies I am looking for a way to render different js files based on which scenario I am handling, instead of using ...

Creating a custom class implementation in JavaScript and initializing it with a constructor function

Perhaps there is a similar question out there, but I haven't come across it yet and I'm still facing an issue. Here's what I've tried: function createClass(obj) { const constructor = obj.constructor; constructor.prototype = obj; ...

Tips for populating div elements using javascript/jquery

I have encountered an issue with displaying data from MYSQL using innerHTML. When I try to use +=, it concatenates all the values in the array instead of creating new elements in the div. How can I resolve this? jQuery(document).ready( function() { $(".dr ...

Validation for a datepicker embedded within a table

I'm facing a challenge and need some assistance. I want to validate if the "FROM (DATE)" is greater than the "TO (DATE)" without disabling the date selection, but instead prompting the user if the condition is not met. Any insights or solutions would ...

What strategies can I use to refactor this controller in Angular 1.5 to make it more concise and efficient

I am encountering an issue with a component I have that contains a button. Whenever the button is clicked, it triggers one of two backend services depending on where the component is located. To achieve this, I am currently passing a flag to the component ...

Changing the color of dots in a React Material-UI timeline

Hey there, I'm trying to change the default color of the MUI TimelineDot component. I attempted to do so by adding this code: <TimelineDot sx={{ '& .MuiTimelineDot-root': { backgroundColor: '#00FF00' }, }} /> Unfortunate ...

Utilize ASP.NET WCF to seamlessly transform a dictionary into JSON format, excluding the use of the "Key" and "Value" tags

I have encountered a problem with my RESTful ASP.NET service. I am attempting to make a function return a JSON string in a specific format: {"Test1Key":"Test1Value","Test2Key":"Test2Value","Test3Key":"Test3Value"} However, the output I am receiving is in ...

Loop through your elements seamlessly with the innovative Jquery loop plugin

After working on the code for my jQuery plugin, here is a snippet that has been causing confusion: for (var counter = 1; counter <= 3; counter++) { var btn = $("<a></a>").addClass(class1) .addClass(class2 + cou ...