Adding and removing classes in NativeScript: A step-by-step guide

Attempting to lower the opacity of my StackLayout while making an Ajax API call.

The structure of my page is as follows:

<Page loaded="pageLoaded" class="page"
    xmlns="http://www.nativescript.org/tns.xsd">
    <ActionBar title="Settings" class="action-bar">
    </ActionBar>

    <ScrollView>
        <StackLayout id="layout" >
            <Image src="~/images/header-logo.jpg" stretch="fit" />
            <GridLayout rows="auto, auto">

                <Label
                    text="Hey Welcome! You need to come up with a username. You only have to do this once."  row="0" textWrap="true" class="labelMessage" />
                <TextField id="username" text="{{ username }}"
                    hint="Any username you want" 
                    returnPress="doneTap" autocorrect="false"
                    autocapitalizationType="none" row="1" />

                <ActivityIndicator busy="{{ authenticating }}" />
            </GridLayout>
            <Button text="Save Username" id="registerButton"
                tap="{{ register }}" returnKeyType="done" class="button" />


        </StackLayout>
    </ScrollView>
</Page>

Snippet from View Model...


register: function () {

    if (this.username == null || this.username.length < 4) {
        alert("Come on, enter a username with at least 4 letters!");
        return;
    }

    this.authenticating = true; 

CSS code for modifying opacity:

.dimPage {

   opacity: 0.3;

}

** Unsuccessful Attempts ** Struggling to add and remove a class through JavaScript. Tried the following method:

settings-page.js

var frameModule = require("tns-core-modules/ui/frame");

var SettingsViewModel = require("./settings-view-model");
var settingsViewModel = new SettingsViewModel();

var pgStackLayout;
var txtUsername;


function pageLoaded(args) {
    var page = args.object;
    var pgStackLayout = null;

    pgStackLayout = page.getViewById("layout");

    page.bindingContext = settingsViewModel;
}

exports.pageLoaded = pageLoaded;

and my settings-viewmodel.js

(snippet when dimming)
pgStackLayout.className = "dimPage";

(snippet when back to full opacity)
pgStackLayout.className = "";

Error encountered stating pgStackLayout is undefined.

Seeking assistance in adding and removing a class on StackLayout to change opacity during an Ajax call.

Appreciate any guidance provided.

Answer №1

After fully immersing myself in the DOCS and honing my skills in the PlayGround... Resolved

I decided to take a slightly different approach to achieve the results I was aiming for. Interestingly, this approach seems to be quite common as I encountered it multiple times while researching the issue.

For future readers seeking to manipulate classes within the core NativeScript application, the following method worked effectively for me.

Restating the Initial Problem I needed to both add and remove a class from a specific element on my page at a particular moment, all through JavaScript (or view model).

Specifically, my goal was to reduce the opacity of a specific StackLayout when a certain element was clicked.

My Solution While there are numerous ways to accomplish this task, as a novice NS Developer, I found this straightforward approach:

// [ ... snippet taken from my view model code ]
//
// Handling the Tap Event
topTap: function (args) {
      const tLabel = args.object; // obtaining the Label that was tapped
      elStack = tLabel.parent; // identifying the parent element of the Label, which happens to be the
                               // required StackLayout.

      elStack.className = "dimPage";  // simply adding an existing CSS class
    },

To revert the element's opacity back to its original state, I merely used an empty string:

     elStack.className = "";  // removing the previously added class name

The ID Approach - An Alternative Method Once I grasped how to access the parent element, I could then locate ANY element using its ID:

... [ slightly modifying the above snippet ]

      // Imagining our StackLayout appears somewhat like this in our XML...
      <StackLayout id="MyStackLayout" height="100%" row="1">

      // To find elements by ID, the view module needs to be imported first
      const view = require("tns-core-modules/ui/core/view");

      topTap: function (args) {
          const tLabel = args.object; // handle to the tapped element
          parent = tLabel.parent;     // retrieving the parent reference once more
          if(parent) {                // ensuring we have obtained the parent successfully
              let myStack = view.getViewById(parent, "MyStackLayout");   // fetching the view
              myStack.className = "dimPage";   // applying the class
          }

    },

Dynamically Adding CSS at the Page Level I also discovered that CSS rules can be included at the Page level by just passing a string:

// This immediately dims the opacity of the StackLayout(s)
page.addCss("StackLayout {opacity: 0.3}");

// ...to restore
page.addCss("StackLayout {opacity: 1.0}");

Gathering My Thoughts on This... I swiftly learned that learning the fundamental concept of acquiring a view's handle (referencing it within your code) is crucial in NativeScript.

Once you master this, manipulating elements on the page becomes quite simple.

An approach I observed frequently in obtaining a page handle is assigning it to a global variable during page load:

var _page;     // Our "Global" page variable accessible throughout the script

function pageLoaded(args) {
  _page = args.object;

}

This concludes what is needed to know about dynamic classes within my Page. Please bear in mind that the content in this post comes from a relatively new NativeScript developer, so I apologize if these concepts appear very basic and intended for beginners. I wanted to share my learning journey with fellow newcomers.

Till next time...

John

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

Error code 12030: AJAX request status

When making an ajax XMLHttpRequest using the POST method, I am encountering a readyState of 4 with a status of 12030. It is known that 12030 is a Microsoft-specific state code indicating that the connection was not sustained. However, I have been unable to ...

Most effective method for adjusting image size to match div container (as background)

I'm attempting to create a background with 85% height and 100% width on the index page using Bootstrap 4. However, when I set an image as the background in a div, it doesn't resize correctly and only shows a portion of the image (as the image is ...

Expanding your knowledge of AngularJS: utilizing ng-click to interact with elements

After a user clicks on an element in my app, I have some logic that runs. For example: html <h3 ng-click="showAlert('text')">this is text! (try to click and select)</h3> js $scope.showAlert = function(text) { console.log(' ...

Can you help understand the unexpected output produced by this JavaScript code?

When looking at the following JavaScript code, you would expect an output of 32. However, the actual answer is 16. How is this possible? 5 + 1 = 6; 6 + 5 = 11; 11 * 2 = 22; 22 + 10 = 32; (this should have been the correct answer) var x = 5; x = (x++, a ...

I am looking for a pair of HTML tags that will allow one to be visible while the other is hidden, and then switch when needed

I am in the process of constructing a webpage dedicated to learning Japanese vocabulary. Each word will be presented within a sentence, just like the example shown below. 森林に散歩する take a walk in the forest In order to facilitate the practic ...

What is the best way to erase information displayed when hovering over an element using mouseout?

Whenever the user hovers over an image, an information box appears regarding that specific image. The information inside the box changes as I move over another image, but when not hovering over any images, the information box remains visible. Unfortunately ...

Differences in Column Height between Bootstrap 4 on Mobile and Desktop Devices

My design includes two columns on desktop, each with a size of 6. https://i.sstatic.net/M33c8.png However, on mobile, I want these columns to adjust to the height of the phone screen. https://i.sstatic.net/3Z44d.png Is there a way to make the height va ...

Using JavaScript to search JSON objects based on key value pairs

Consider a scenario where you have an array of objects in users.json: {"key":"userSubscriptions","value": [{"channel":"Netflix","user":"Bobby","region":"NA"}, [{" ...

The functionality of jQuery smooth scrolling to an anchor is only effective when the page is at the top and there is

Currently, I am working on designing a simple one-page website featuring a fixed menu that smoothly scrolls to specific sections on the page upon clicking the menu items. However, I have encountered an issue where the scrolling works perfectly only when t ...

What is the process for displaying the ™ symbol above the XYZ text?

How can I position the ™ symbol slightly above the XYZ text? <div> <div style="display: inline-block; border: 1px solid red;"> XYZ </div> <div style="font-size: 0.6em; border: 1px solid red; display: in ...

Coordinating a series of maneuvers

When it comes to coordinating multiple sequential actions in Redux, I find it a bit confusing. I have an application with a summary panel on the left and a CRUD panel on the right. My goal is to have the app automatically update the summary after a CRUD op ...

Where is the function returned by redux-thunk invoked?

Can you help me understand where the function returned by addUser is being called in this action creator and redux thunk function? const userAdded = () => ({ type: types.ADD_USER, }); export const addUser = (user) => { return function (dispat ...

Displaying and Concealing Table Rows using Javascript

I am working with an array of prices that are being displayed in a table using a foreach loop. The goal is to hide specific rows in the table based on certain conditions. The $status variable is set to "YES" if the price is => 30, and "NO" if the price ...

There is a syntax error in the for-loop within the AngularJS $http.get causing an unexpected identifier

I'm encountering a 'syntax error: unexpected identifier' and my browser seems to be getting stuck in a loop after executing this code. I figured incorporating setInterval for delaying API requests was a sound strategy according to the API re ...

The Bootstrap Tooltip seems to be glued in place

Utilizing jQuery, I am dynamically generating a div that includes add and close buttons. Bootstrap tooltips are applied to these buttons for additional functionality. However, a problem arises where the tooltip for the first add button remains visible even ...

Node.js http module unable to serve html file

I have been attempting to serve an HTML page as a response to the '/' request on my HTTP server, but unfortunately, it doesn't seem to be working. The content of my index.html file is as follows: <html> <head> <title> ...

assigning the browser's width to a variable within an scss file

Is there a way to dynamically set the browser's width as a variable? I am familiar with @media queries, but I need to calculate the browser's width for a specific purpose. I attempted using jQuery to achieve this, and it works well with a fixed ...

Creating a 3-column grid in React using the map function is a simple and efficient way

Looking to arrange my cards in a specific grid pattern: [] [] [] [] [] [] [] [] [] ... ... Facing an issue with rendering items using the map function. I've attempted a solution, but it's not working as expected. To create a new row for every in ...

Troubleshooting jsPDF problem with multi-page content in React and HTML: Converting HTML to PDF

I need to convert HTML content in my React application into a PDF file. My current approach involves taking an HTML container and executing the following code snippet: await htmlToImage .toPng(node) .then((dataUrl) => { ...

The responses from Fetch and Postman vary in their outputs

While developing my react flask-rest site, I came across some unexpected behavior related to a specific issue. When I send a get request to the domain/api/users/1 endpoint in Postman where 1 represents the id of a deleted database element, I receive a resp ...