PDF-lib.js unable to measure and fill text in a multiline text field correctly

I’m working on a PDF form where I need to restrict a multiline text field from being overfilled. The idea is to prevent users from entering more text than the field can visually accommodate. However, I’m running into an issue with text measurement.

For example, when measuring a string like “T.”, “Te”, “V.”, etc. the library I’m using calculates the dot/letter as if it starts directly under the horizontal bar of the “T” (and right next to its vertical stroke). In the actual rendered PDF, though, the dot appears to start after the horizontal line of the “T”. This discrepancy means that my measurement logic—which relies on calculating the total width of the text—ends up misjudging when the text has reached the maximum allowable width.

The issue is that the measurement (using context.measureText()) doesn’t reflect the actual rendered spacing in the PDF—especially for cases like “T.” where parts of glyphs overlap or have unusual kerning. I’ve tried per-character measurements and other tweaks, but I still face problems because some letters seem to overlap or “stick” together in the measurement while, in the final PDF rendering, they have natural spacing.

Has anyone encountered this problem before? Is there a library or a more reliable approach to measure and restrict text that takes into account the nuances of glyph positioning and kerning as rendered in PDFs?

This would work, if the measurement was using the same font as the rendered PDF.

I’ve tried various approaches:

  • Measuring each character individually and summing their widths.
  • Using canvas metrics and even adjusting for kerning.

but I have no clue what the kerning is etc. it is always out by a lot and not really a good method.

const textField = document.getElementById('text');
const statusMessage = document.getElementById('statusMessage');
const maxTextWidth = 600; // Maximum width per line in pixels
const allowedLines = 12;

// Create an offscreen canvas for text measurement
const measurementCanvas = document.createElement('canvas');
const measurementContext = measurementCanvas.getContext('2d');
measurementContext.font = '10pt Arial';

// Function to count how many wrapped lines the text occupies
function getWrappedLineCount(text, maxWidth, context) {
    let lines = 0;
    const paragraphs = text.split('n');
    paragraphs.forEach(para => {
        if (para === "") {
            lines++;
        } else {
            const words = para.split(' ');
            let line = '';
            words.forEach(word => {
                const testLine = line ? line + ' ' + word : word;
                if (context.measureText(testLine).width > maxWidth && line !== '') {
                    lines++;
                    line = word;
                } else {
                    line = testLine;
                }
            });
            if (line !== '') {
                lines++;
            }
        }
    });
    return lines;
}

// Listen for input on the multiline text field and restrict further input if needed
textField.addEventListener('input', function() {
    let text = textField.value;
    let lines = getWrappedLineCount(text, maxTextWidth, measurementContext);
    if (lines <= allowedLines) {
        statusMessage.textContent = "Platz vorhanden";
        statusMessage.style.color = "green";
    } else {
        // Trim the text until it fits within the allowed lines.
        while (getWrappedLineCount(text, maxTextWidth, measurementContext) > allowedLines && text.length > 0) {
            text = text.slice(0, -1);
        }
        textField.value = text;
        statusMessage.textContent = "Keine Zeicheneingabe mehr möglich";
        statusMessage.style.color = "red";
    }
});

Failed to load resource. 404 error. Can’t load images or js files

There are link problems when loading resources. Can’t figure out why.

I have a song-history.js file in /component folder and I’m trying to load it:

<script src="/components/song-history.js" type="text/javascript"></script>

But I’m getting an error :

GET http://localhost:8080/components/song-history.js net::ERR_ABORTED 404 (Not Found)

The same with images that are /icons folder.

<img id="img" src="/icons/up.png">

And I’m getting:

GET http://localhost:8080/icons/equal.png 404 (Not Found)

Here’s my directory structure:

enter image description here

I tried renaming folders, moving them, moving files to the root – nothing helped.
When I’m trying to open links, e.g. http:// localhost:8080/icons/re.png I get the message

Type Status Report
Message JSP file [/icons/main.jsp] not found
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

I’m not sure why it’s even searching for main.jsp there.

Can anyone help? 🙂

Access child data from parent with AlpineJS

AlpineJS’ x-data can be nested, so one can access parent data inside a child.

But can one access child data from its parent?

Contrived example:

<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>

<div x-data="{ get nAvailable() { return $el.querySelectorAll('.product.avail').length },
               get nSoldOut()   { return $el.querySelectorAll('.product:not(.avail)').length },
             }">

  <div x-data="{ avail: true }"  class="product" x-bind:class="avail && 'avail'">Product 1</div>
  <div x-data="{ avail: true }"  class="product" x-bind:class="avail && 'avail'">Product 2</div>
  <div x-data="{ avail: true }"  class="product" x-bind:class="avail && 'avail'">Product 3</div>
  <div x-data="{ avail: true }"  class="product" x-bind:class="avail && 'avail'">Product 4</div>
  <div x-data="{ avail: false }" class="product" x-bind:class="avail && 'avail'">Product 5 <span x-text="avail || '(sold out)'"></span></div>

  <br/>
  <div>Available: <span x-text="nAvailable"></span></div>
  <div>Sold out: <span x-text="nSoldOut"></span></div>
</div>

That works.

But child state is converted to a class (.avail) that the parent can detect by scanning the DOM. In a large page that is slow.

Is it possible to do this without that class?

Eas Production build fails, development build works fine

I’m developing an app for iOS using Expo, React Native, Firebase, and JavaScript.
While the development build works flawlessly (npx eas-cli build –profile development –platform ios ), I encounter a problem when creating a production build for TestFlight or the App Store. (npx eas-cli build –platform ios –profile production)
The building process fails every time on “run fastlane”.

BUT: If I just build for production with my app being only a blank page saying “hello world”, the build is successful and i can push the rest of my app (src folder) to testflight with npx eas update 🙂

There are no errors in the XCode logs, only warnings
Fastlane fails on the exact same line every time

Environment:
Expo, React Native, Firebase, JavaScript, Ios

Request for Help
I’m seeking advice or any suggestions on how to resolve this issue. Any insights or guidance would be greatly appreciated.

Feel free to ask for more details if needed.

Package.json:

{
  "name": "tool",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@babel/preset-env": "^7.26.9",
    "@babel/runtime": "^7.26.9",
    "@expo/config-plugins": "^9.0.16",
    "@expo/prebuild-config": "^8.0.28",
    "@react-native-async-storage/async-storage": "1.23.1",
    "@react-native-community/datetimepicker": "8.2.0",
    "@react-native-community/slider": "4.5.5",
    "@react-native-firebase/analytics": "^21.12.0",
    "@react-native-firebase/app": "^21.12.0",
    "@react-native-firebase/auth": "^21.12.0",
    "@react-native-firebase/firestore": "^21.12.0",
    "@react-native-firebase/messaging": "^21.12.0",
    "@react-navigation/bottom-tabs": "^7.2.1",
    "@react-navigation/native": "^7.0.15",
    "@react-navigation/stack": "^7.1.2",
    "axios": "^1.8.1",
    "d3-scale": "^4.0.2",
    "date-fns": "^4.1.0",
    "depcheck": "^1.4.7",
    "expo": "~52.0.38",
    "expo-application": "~6.0.2",
    "expo-asset": "~11.0.4",
    "expo-auth-session": "~6.0.3",
    "expo-av": "~15.0.2",
    "expo-build-properties": "~0.13.2",
    "expo-constants": "~17.0.8",
    "expo-dev-client": "~5.0.13",
    "expo-device": "~7.0.2",
    "expo-haptics": "~14.0.1",
    "expo-notifications": "~0.29.14",
    "expo-status-bar": "~2.0.1",
    "expo-store-review": "~8.0.1",
    "expo-updates": "~0.27.3",
    "expo-web-browser": "~14.0.2",
    "firebase": "^11.4.0",
    "moment": "^2.30.1",
    "prop-types": "^15.8.1",
    "react": "18.3.1",
    "react-native": "0.76.7",
    "react-native-bouncy-checkbox": "^4.1.2",
    "react-native-calendars": "^1.1310.0",
    "react-native-chart-kit": "^6.12.0",
    "react-native-confetti-cannon": "^1.5.2",
    "react-native-dotenv": "^3.4.11",
    "react-native-draggable-flatlist": "^4.0.1",
    "react-native-elements": "^3.4.3",
    "react-native-gesture-handler": "~2.20.2",
    "react-native-paper": "^5.13.1",
    "react-native-purchases": "^8.8.0",
    "react-native-reanimated": "~3.16.1",
    "react-native-safe-area-context": "4.12.0",
    "react-native-screens": "~4.4.0",
    "react-native-svg": "15.8.0",
    "react-native-vector-icons": "^10.2.0",
    "typescript": "^5.8.2"
  },
  "devDependencies": {
    "@babel/core": "^7.24.0",
    "dotenv": "^16.4.7"
  },
  "resolutions": {
    "string-width": "4.2.3",
    "wrap-ansi": "7.0.0"
  },
  "private": true
}

eas.json:

{
  "cli": {
    "version": ">= 15.0.14",
    "appVersionSource": "remote"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "channel": "development",
      "ios": {
        "resourceClass": "medium"
      },
      "environment": "development"
    },
    "preview": {
      "distribution": "internal",
      "channel": "preview",
      "ios": {
        "resourceClass": "medium"
      },
      "environment": "preview"
    },
    "production": {
      "channel": "production",
      "distribution": "store",
      "autoIncrement": true,
      "ios": {
        "resourceClass": "large",
        "cocoapods": "1.16.2",
        "buildConfiguration": "Release",
        "image": "latest"
      },
      "android": {
        "buildType": "app-bundle"
      },
      "environment": "production"
    }
  },
  "submit": {
    "production": {
      "ios": {
        "appleId": "xx",
        "ascAppId": "xx",
        "appleTeamId": "xx"
      }
    }
  }
}

enter image description hereenter image description hereenter image description here

What I’ve Tried:

  • Checked all certificates and provisioning profiles
  • checked documentation
  • tried a lot of stuff for 50+ hours,
  • tried building with ressourceclass large
  • Removed push notifications

Error when building and launching vue project

My vue js project at server startup should be built with webpack and then run with exspress js, but I get the following error

ERROR Error: Build failed with errors.
Error: Build failed with errors.
at C:UsersAdminMarketplaysnode_modules@vuecli-servicelibcommandsbuildindex.js:207:23
at C:UsersAdminMarketplaysnode_moduleswebpacklibwebpack.js:168:8
at C:UsersAdminMarketplaysnode_moduleswebpacklibHookWebpackError.js:67:2
at Hook.eval [as callAsync] (eval at create (C:UsersAdminMarketplaysnode_modulestapablelibHookCodeFactory.js:33:10), :6:1)
at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (C:UsersAdminMarketplaysnode_modulestapablelibHook.js:18:14)
at Cache.shutdown (C:UsersAdminMarketplaysnode_moduleswebpacklibCache.js:154:23)
at C:UsersAdminMarketplaysnode_moduleswebpacklibCompiler.js:1379:15
at Hook.eval [as callAsync] (eval at create (C:UsersAdminMarketplaysnode_modulestapablelibHookCodeFactory.js:33:10), :6:1)
at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (C:UsersAdminMarketplaysnode_modulestapablelibHook.js:18:14)
at Compiler.close (C:UsersAdminMarketplaysnode_moduleswebpacklibCompiler.js:1372:23)

In webpack and vue configurations I wrote seemingly everything I needed, but still didn’t work. Before this asked for libraries to support css, they are installed, now it’s not clear what is being asked for

vue configurations:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  configureWebpack: {
    plugins: [
      new MiniCssExtractPlugin({
        filename: '[name].css',
        chunkFilename: '[id].css',
      }),
    ],
  },
  chainWebpack: config => {
    config.module
      .rule('css')
      .uses.clear(); 

    config.module
      .rule('css')
      .test(/.css$/)
      .use('style-loader')
      .loader('style-loader');

    config.module
      .rule('css')
      .use('css-loader')
      .loader('css-loader')
      .options({
        modules: true,
        sourceMap: true,
      });

    config.plugins.delete('extract-css'); 
  },
};

module.exports = {
  configureWebpack: {
    module: {
      rules: [
        {
          test: /.css$/,
          use: ['style-loader', 'css-loader'],
        },
      ],
    },
  },
};

webpack configuration:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/main.js', 
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html' 
    })
  ],
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000
  }
};


     const MiniCssExtractPlugin = require('mini-css-extract-plugin');
     
     module.exports = {
       plugins: [
         new MiniCssExtractPlugin({
           filename: '[name].css',
           chunkFilename: '[id].css'
         })
       ],
       module: {
         rules: [
           {
             test: /.css$/,
             use: [
               MiniCssExtractPlugin.loader,
               'css-loader'
             ]
           }
         ]
       }
     };
     

I have installed all the necessary css libraries, installed vue-cli, re-configured the dependencies, cleared the cache, but when I run the project it gives the above error.

Why image not upload using ajax but done directly in php?

I want to create and save image in upload folder but this work is done correctly when i directly hit php (upload) file. otherwise using ajax success function give me done but not image upload.

  $(document).ready(function(){
  $("#form").on('submit', function(e) {
  e.preventDefault();
  $('.spinner-border').show();
  // Submit the form data to the server using jQuery AJAX
  $.ajax({
  url: "icoup.php",
  type: "POST",
  data:  new FormData(this),
  contentType: false,
  cache: false,
  processData: false,
  // beforeSend: function() {
  //   $("").fadeOut();
  // },
  success: function(data) {
    console.log(data);
    // $('#dat').html(data);
    $(".cbox4").show();
    $('.cbox').hide();
    $('.cbox3').show();
   
   //   if (data == 'invalid') {
   //     $("#err").html("Invalid File!").fadeIn();
   //   } else {
   //     $("#preview").html(data).fadeIn();
   //     $("#form")[0].reset(); 
   //   }
   },
   error: function(e) {
   //   $("#err").html(e).fadeIn();
   }          
  });

its my ajax..

<?php
function compress_image($s,$d,$q) {
$info = getimagesize($s);
if($info['mime']=='image/jpeg'){$image = imagecreatefromjpeg($s);}
elseif($info['mime']=='image/png'){$image = imagecreatefrompng($s);}
elseif($info['mime']=='image/gif'){$image = imagecreatefromgif($s);}
elseif($info['mime']=='image/jpg'){$image = imagecreatefromjpeg($s);}
imagejpeg($image,$d,$q);
}
if(isset($_POST['submit'])){
$image  = $_FILES['file']['tmp_name'];
$source_image = $image;
$newname = 'Boxx_'.time();
$newnumber = rand(100, 1000);
$fname = $newname.'_'.$newnumber.'.jpeg';
$destini = 'uploads/'.$fname;
compress_image($source_image,$destini,60);

}

?> 

its my php code | ANY ONE tell me how to solve it

How to update the content page using bootstrap

I must be stupid but I really don’t get how to update the page content when item in a bootstrap sidebar is clicked. All examples I find are just showing how to create a responsive sidebar but ends there. E.g. following this https://www.geeksforgeeks.org/how-to-create-a-responsive-sidebar-in-bootstrap-5/ only gets the boilerplate up.
What I want is to have each of the items in the sidebar to load a section to the right of the sidebar with a new div . The way I do it now is with javascript

window.addEventListener("hashchange", (event) => {
  let allPages = [
    "#network",
    "#tally",
    "#mesh",
    "#admin",
  ];

  allPages.splice(allPages.indexOf(window.location.hash), 1);
  $( window.location.hash ).removeClass("d-none");
  allPages.forEach(item => {
    $( item ).addClass("d-none");
  });
  $("#pageTitle").html(window.location.hash.replace("#", ""));
});

But it must be a better way of doing it. Also, the selected item in the sidebar does not update….

Edited after comment:

Basically i just copied the link code straight off, changed some of the links et.c. Problem is in the <main> tag there , how to change the content. My approach is to hide/show the divs using bootstrap classes, but there must be a better way. And the sidebars active item does not update when clicking it, of course since I have not programed it to do that, but how do I do that 🙂 .

 <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0">
      <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">dashboard</a>
      <ul class="navbar-nav px-3">
        <li class="nav-item text-nowrap">
          <a class="nav-link" href="#">Sign out</a>
        </li>
      </ul>
    </nav>
        
    <div class="container-fluid">
      <div class="row">
        <nav class="col-md-2 d-none d-md-block bg-light sidebar">
          <div class="sidebar-sticky">
            <ul class="nav flex-column">
              <li class="nav-item">
                <a class="nav-link active" href="#network">
                  <span data-feather="globe"></span>
                  Network <span class="sr-only">(current)</span>
                </a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#tally">
                  <span data-feather="sun"></span>
                  Tally
                </a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#board">
                  <span data-feather="hard-drive"></span>
                  Board
                </a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#mesh">
                  <span data-feather="share-2"></span>
                  Mesh
                </a>
              </li>
               <li class="nav-item">
                <a class="nav-link" href="#admin">
                  <span data-feather="user"></span>
                  Admin
                </a>
              </li>
            </ul>
            <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
              <span>Saved configurations</span>
              <a class="d-flex align-items-center text-muted" href="#">
                <span data-feather="plus-circle"></span>
              </a>
            </h6>
            <ul class="nav flex-column mb-2">
              <li class="nav-item">
                <a class="nav-link" href="#">
                  <span data-feather="file-text"></span>
                  example
                </a>
              </li>
            </ul>
          </div>
        </nav>
     
        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
                
          <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom">
            <h1 id="pageTitle" class="h2">Network</h1>
          </div>
          <div id="network" class="justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3">
            <form action="/network">
              <div class="form-group">
                <label for="ssid">WiFi SSID:</label>
                <input type="text" class="form-control" required id="ssid" name="ssid" value="%WIFI_SSID%" list="foundWifis">
                <datalist id="foundWifis">
                %FOUND_WIFI_NETWORKS%
                </datalist>
              </div>
              <div class="form-group">
                <label for="wpwd">WiFi Password:</label>
                <input type="password" class="form-control" required id="wpwd" value="%WIFI_PWD%" name="wpwd">
              </div>

              <div class="form-group">
              <label for="manual">Manual configuration</label>
                <input type="checkbox" id="manual" name="Manual" %MANUAL_CFG% onclick="disableUnused()"></p>

                <div id="manualCfg">
                        <label for="tid">IP</label>
                        <input type="text" minlength="7" maxlength="15" required pattern="^((d|[1-9]d|1dd|2[0-4]d|25[0-5]).){3}(d|[1-9]d|1dd|2[0-4]d|25[0-5])$" id="tip" name="tip" value="%TALLY_IP%">

                        <label for="tnmid">netmask:</label>
                        <input type="text" minlength="7" maxlength="15" required pattern="^((d|[1-9]d|1dd|2[0-4]d|25[0-5]).){3}(d|[1-9]d|1dd|2[0-4]d|25[0-5])$" id="tnm" name="tnm" value="%TALLY_NETMASK%">
                </div>
             </div>


             <button type="submit" class="btn btn-primary">Update</button>
            </form>
          </div>
          <div id="tally" class="d-none justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3">
            <form action="/tally">
                <div class="form-group">
                  <label for="gsip">Target IP</label>
                  <input type="text" class="form-control" minlength="7" maxlength="15"  required pattern="^((d|[1-9]d|1dd|2[0-4]d|25[0-5]).){3}(d|[1-9]d|1dd|2[0-4]d|25[0-5])$" id="gsip" name="gsip" value="%TARGET_IP%">
                </div>
                <div class="form-group">
                  <label for="smart">Smart assign</label>
                  <input type="checkbox" id="smart" %SMART_MODE% name="smart" onclick="disableUnused()">
                </div>
             <button type="submit" class="btn btn-primary">Update</button>
            </form>
          </div>
        </main>

Using declarativeNetRequest to “modifyHeaders” dynamically by a function call

I’m mocking a Chrome extension which should modify HTTP request headers dynamically. The extension works as expected with a static value provided in “modifyHeaders” rule, but I can’t figure out how to calculate the value dynamically via function. All attempts leads to errors “Uncaught SyntaxError: Unexpected identifier ‘getValue'” (if I define the function) or ‘self’ (if I embed the expression directly into the rule).

  const MY_CUSTOM_RULE_ID = 1
  chrome.declarativeNetRequest.updateDynamicRules({
    removeRuleIds: [MY_CUSTOM_RULE_ID],
    addRules: [
        {
            id: MY_CUSTOM_RULE_ID,
            priority: 1,
            action: {
                type: "modifyHeaders",
                requestHeaders: [
                    {
                        getValue: async function() { return btoa(String.fromCharCode(...new Uint8Array((await self.crypto.subtle.digest("SHA-256", new TextEncoder().encode("my custom header value"))))));  },
                        operation: "set",
                        header: "my custom name",
                        value: await getValue()
                    }
                ]
            },
            condition: {
                "resourceTypes": ["main_frame", "sub_frame"]
            },
        }
      ],
  });

The above code is the current background.js. The final task implies that the value is calculated via crypto.

OAuth2Client Email Not Returned google-auth-library | NodeJs

I’m trying to verify a Google Sign-In ID Token in my Node.js backend using the google-auth-library. However, the verifyIdToken function does not return the payload, and I’m unable to retrieve the user information. But it gives other info iss, iat, exp, nonce. Not email, profile pic url included why?

const { OAuth2Client } = require('google-auth-library');

const webClientId = process.env.OAUTH_GOOGLE_WEB_CLIENT_ID; // Web Client ID
const androidClientId = process.env.OAUTH_GOOGLE_ANDROID_CLIENT_ID; // Android Client ID

async function verifyIdToken(idToken) {
    const client = new OAuth2Client(webClientId);
    try {
        const ticket = await client.verifyIdToken({
            idToken: idToken,
            audience: [webClientId, androidClientId], // Allow multiple audiences
        });

        const payload = ticket.getPayload();
        console.log(payload); // Debugging output

        if (!payload) {
            throw new Error('Invalid token payload');
        }

        return payload;
    } catch (error) {
        console.error("Verification Error:", error.message);
        throw new Error('Failed to verify ID Token');
    }
}

Dropzone.js max file size is triggering queuecomplete event

I have a dropzone implemented with JavaScript. I want to handle situations where a user tries to upload a file that exceeds the maximum file size. Specifically, I want to remove the file and display a modal alert informing the user about the issue.

My problem is that when someone uploads a file that exceeds the maximum file size, it triggers the queuecomplete event and the window navigates to another page. How can I manage this issue without triggering the queuecomplete event?

This is the dropzone:

var myDropzone = new Dropzone("#dropzoneFileUpload", { 
    url: appRootUrl  + "someUrl",
    autoProcessQueue:false,
    paramName: "file",
    addRemoveLinks: true,
    dictRemoveFile: "Eliminar fichero",
    dictCancelUpload: "Cancelar subida",
    maxFiles: 20,
    parallelUploads: 20,
    maxFilesize: 50,
    init: function () {
        thisDropzone = this;
    },
    accept: function(file, done) {
        var thumbnail = $('.dropzone .dz-preview.dz-file-preview .dz-image:last');
        //Cuando alguien sube un archivo al dropzone este switchcase pinta imagenes segun el tipo de archivo
        switch (file.type) {
          case 'application/pdf':
            thumbnail.css('background', 'url(https://upload.wikimedia.org/wikipedia/commons/thumb/9/94/PDF_icon_-_grey-red_-_16px.svg/120px-PDF_icon_-_grey-red_-_16px.svg.png?20210526135026)');
            break;
          case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
            thumbnail.css('background', 'url(https://upload.wikimedia.org/wikipedia/commons/f/fb/.docx_icon.svg)');
            break;
          case 'application/vnd.ms-excel':
                thumbnail.css('background', 'url(https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/Xls_icon_%282000-03%29.svg/1024px-Xls_icon_%282000-03%29.svg.png)');
            break;
          default:
            break;
        }
        if (file.size > this.options.maxFilesize * 1024 * 1024) {
            thisDropzone.removeFile(file);
            $("#aviso").text("El archivo '"+file.name+"' excede el tamaño máximo permitido (" + this.options.maxFilesize + "Mb).");
            $("#myModalAviso").modal("show");
        }
        else if (checkFileName(file.name)) {
            thisDropzone.removeFile(file);
            $("#aviso").text("El archivo '"+file.name+"' no se admite debido a que el nombre del archivo contiene un punto.");
            $("#myModalAviso").modal("show");
            return;
        }
        else{
            done();
        }
      }
});

myDropzone.on("queuecomplete", function() {
    let detalle = $("#detalle").val();
    if(detalle == "true"){
        window.location.href = "/someUrl/"+$("#id").val();
    }
    else{
        window.location.href = "/someUrl/";
    }
});

This are some other ways i tried:

myDropzone.on("error", function(file, message) { 
    alert(message);
    this.removeFile(file); 
});

myDropzone.on("addedfile", function(file) {
    event.preventDefault()
    if (file.size > this.options.maxFilesize * 1024 * 1024) {
       thisDropzone.removeFile(file);
        $("#aviso").text("El archivo '"+file.name+"' excede el tamaño máximo permitido (" + this.options.maxFilesize + "Mb).");
        $("#myModalAviso").modal("show");
    }
});

Thank you.

Echarts stacked bar chart / waterfall chart unable to create

I’m trying to make a stacked bar chart / waterfall chart and I am having a lot of difficulties setting it up. I’m using echarts with vue, but the framework doesn’t matter that much. Any help regarding setting this up in echarts would be extremely helpful!

It needs to look like this:
Sample chart stacked.

The following code is what I ended up with, which just creates randomly generated data as a mock.

import { defineComponent, ref, onMounted } from 'vue';
import { use } from 'echarts/core';
import VChart from 'vue-echarts';
import { BarChart } from 'echarts/charts';
import { GridComponent, TooltipComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';

use([BarChart, GridComponent, TooltipComponent, CanvasRenderer]);

export default defineComponent({
  components: {
    VChart,
  },
  setup() {
    const timeIntervals = ref([]);
    
    const updateTimeIntervals = () => {
      const intervals = [];
      let startTime = new Date();
      startTime.setMinutes(0, 0, 0);
      for (let i = 0; i < 8; i++) { // 8 hours with 1-hour intervals
        intervals.push(
          startTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
        );
        startTime.setHours(startTime.getHours() + 1);
      }
      timeIntervals.value = intervals;
    };
    
    onMounted(updateTimeIntervals);
    
    const chartOptions = ref({
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'shadow' },
      },
      xAxis: {
        type: 'category',
        data: timeIntervals,
        axisLabel: { rotate: 45 },
      },
      yAxis: {
        type: 'value',
        min: -100,
        max: 100,
      },
      series: [
        {
          name: 'Category A',
          type: 'bar',
          stack: 'total',
          data: Array.from({ length: 8 }, () => Math.floor(Math.random() * 200 - 100)),
          color: '#5470c6',
        },
        {
          name: 'Category A (Duplicate)',
          type: 'bar',
          stack: 'total',
          data: Array.from({ length: 8 }, () => Math.floor(Math.random() * 200 - 100)),
          color: '#91cc75',
        },
        {
          name: 'Category B',
          type: 'bar',
          stack: 'total',
          data: Array.from({ length: 8 }, () => Math.floor(Math.random() * 200 - 100)),
          color: '#fac858',
        },
        {
          name: 'Category C',
          type: 'bar',
          stack: 'total',
          data: Array.from({ length: 8 }, () => Math.floor(Math.random() * 200 - 100)),
          color: '#ee6666',
        },
        {
          name: 'Category D',
          type: 'bar',
          stack: 'total',
          data: Array.from({ length: 8 }, () => Math.floor(Math.random() * 200 - 100)),
          color: '#73c0de',
        },
      ],
    });
    
    return { chartOptions, timeIntervals };
  },
});

The code above generates something like this which has multiple where htings where items overlap, not centered in 0 (this is because of mock data) and it just generally isn’t what I want. But this is the furthest I have come:
enter image description here

Angular 19 Module Federation: “Uncaught SyntaxError: Cannot use ‘import.meta’ outside a module” in remoteEntry.js

I’m trying to build a Module Federation app using Angular 19 and Webpack 5. My setup consists of:

  1. Remote-App: It successfully builds and generates remoteEntry.js, accessible at:
    http://localhost:4201/remoteEntry.js

  2. Host-App: Fails to load mfe-app remoteEntry.js from http://localhost:4201/remoteEntry.js
    in the host application, I get this error in the browser console:
    Uncaught SyntaxError: Cannot use 'import.meta' outside a module (at remoteEntry.js:3629:29)

What I’ve Tried

To resolve this, I attempted the following:

1. Configured Remote-App to use CommonJS instead of ES Modules

Here’s my remote-app webpack.config.js:

const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');

const mfConfig = withModuleFederationPlugin({
name: 'remote-mfe-app',
exposes: {
 './RemoteEntryComponent': './src/app/remote-entry/remote-entry.component.ts'
},
shared: {
 ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
}
});

module.exports = {
...mfConfig,

output: {
 library: {
   type: "commonjs" // Also tried "module" and "umd"
 }
},

experiments: {
 outputModule: false
}
};

2. Configured Host-App to treat remoteEntry.js as CommonJS instead of an ES Module

Here’s my host-app webpack.config.js:

const { withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');

module.exports = withModuleFederationPlugin({
  name: 'mfe-host-app',
  remoteType: 'commonjs',

  remotes: {
    'remote-mfe-app': 'alpha-new-business-mfe@http://localhost:4201/remoteEntry.js'
  },

  shared: {
    singleton: true,
    strictVersion: true,
    requiredVersion: 'auto'
  }
});

Despite all this. The remoteEntry.js file is still generated as ES Module and contain the import.meta I’m trying to avoid. Below is a snippet of remoteEntry.js that is causing this syntax error:
enter image description here

Below is the error I get host-app resulting in remote-app failing to load:
enter image description here

Any suggestion on how to fix this?

Cannot access ‘Component’ before initialization. Circular dependency in Jasmine testing. Angular 17

In the example below, after running ng test –include my-component.component.spec.ts, I’m getting this error:

An error was thrown in afterAll Uncaught ReferenceError: Cannot access
‘MyComponentComponent’ before initialization

I think this is due to a circular dependency, because my component access a route file where the component itself is referenced.

my-component.component.ts

import {Component, OnInit} from '@angular/core';
import {myRoutes} from './my-routes';

@Component({
  selector: 'mi-component',
  template: ``,
})
export class MyComponentComponent implements OnInit {
  ngOnInit(): void {

  }

  routesModification() {
    const routes = myRoutes;
    routes[0].path = '/new-route';
  }
}

my-component.component.spec.ts

import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MyComponentComponent} from './my-component.component';

describe('MyComponentComponent class', () => {
  let component: MyComponentComponent;
  let fixture: ComponentFixture<MyComponentComponent>;
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [MyComponentComponent],
      imports: [],
      providers: [],
    }).compileComponents();

    fixture = TestBed.createComponent(MyComponentComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('El componente deberia estar creado correctamente', () => {
    expect(component).toBeTruthy();
  });
});

my-routes.ts

import {Routes} from '@angular/router';
import {MyComponentComponent} from './my-component.component';

export const myRoutes: Routes = [
  {
    path: '',
    component: MyComponentComponent,
  },
];

I need to fix this so that the test passes without touching the component or the route files, which I am not allowed. This is a problem that occurs only when I launch the test individually, when I launch the application or when I launch ng test globally, no such message appears.

React Native IOS Build failed with `Command PhaseScriptExecution failed with a nonzero exit code`

I am getting this error:

ReactCodegen: Command PhaseScriptExecution failed with a nonzero exit code

This is my Package.json:

  "dependencies": {
    "@react-native-async-storage/async-storage": "^2.1.1",
    "@react-native-vector-icons/common": "^11.0.0",
    "@react-native-vector-icons/ionicons": "^7.4.0",
    "@react-navigation/bottom-tabs": "^7.2.0",
    "@react-navigation/native": "^7.0.14",
    "@react-navigation/native-stack": "^7.2.0",
    "axios": "^1.7.9",
    "formik": "^2.4.6",
    "react": "18.3.1",
    "react-native": "0.77.0",
    "react-native-bouncy-checkbox": "^4.1.2",
    "react-native-image-picker": "^8.1.0",
    "react-native-popover-view": "^6.1.0",
    "react-native-safe-area-context": "^5.2.0",
    "react-native-screens": "^4.6.0",
    "react-native-toast-message": "^2.2.1",
    "react-native-vision-camera": "^4.6.3",
    "react-native-vision-camera-face-detector": "^1.8.1",
    "react-native-worklets-core": "^1.5.0",
    "yup": "^1.6.1"
  },

Screen Shot

How can I submit a form without breaking dynamic content in PHP with JavaScript?

I have a webpage with a navbar menu. When a user clicks on a menu item, it dynamically loads the corresponding PHP file into the home dynamic content section using JavaScript, and the content updates without reloading the page.

One of the menu options displays a message form within the dynamic content area. However, when I submit the form, it redirects to the form.php file, causing the entire page to reload and breaking the dynamic content.

I want to submit the form data without causing a page reload, while keeping the dynamic content intact. I would like to display the success or failure message after submission, without reloading the page.

How can I achieve this using JavaScript to submit the form and display the result without breaking the dynamic content?

home.php

<li class="nav-item m-2"><a href="message.php" id="message" class="nav-link text-white px-3 py-2">message</a></li>

js

function loadPage(event, page) {
        if (event) event.preventDefault(); 

        fetch(page) // Fetch the PHP page
            .then(response => response.text()) 
            .then(data => {
                mainContent.innerHTML = data;
            })
            .catch(error => console.error("Error loading page:", error));
    }if (message) makeTimetable.addEventListener("click", (event) => loadPage(event, "../message.php"));</script>```