How do I insert text into an empty div using javascript

I have tried for several hours to get this to work without any success. I have a site that lists recent posts. I need to insert text into any blank divs within that site. below is the html

<div class="pt-cv-taxoterm below_title"></div>

I haven’t used javascript in many years and so I’m really rusty. I’ve searched on here and found several solutions but none of them work for me for some reason.

Here’s a few that i’ve tried:

if (document.getElementsByClassName('div.pt-cv-taxoterm.below_title').is(':empty')) {
    document.getElementsByClassName('div.pt-cv-taxoterm.below_title').innerHTML = '<a href="https://revtommy.com/sermons/" title="Sermons" class="pt-cv-tax-blog">Sermons</a>';
}
if ($('.pt-cv-taxoterm below_title').is(':empty')){
    document.getElementsByClassName('pt-cv-taxoterm below_title').innerHTML = '<a href="https://revtommy.com/sermons/" title="Sermons" class="pt-cv-tax-blog">Sermons</a>';
}

This is a WordPress site and I’m using a plugin to generate this particular block. It has a spot to add either custom CSS or Javascript for that plugin. Any help would be appreciated.

I tried multiple things that I found on this site.

WordPress Ajax and Plugins

I think I’m nearly there with this, but can’t get the final pieces despite hours of research and trial and error. I have a form on a page in WordPress, and I want users to be able to run database queries based on their form input, then display the results below. So far as I’m aware, the “best” method of doing this is through Ajax.

Where I’m at: I’ve written a simple WordPress plugin comprising of the main php file (systembuilder.php, in the default plugins folder):

<?php
/**
 * Plugin Name: System Builder

**/



function builder_init() {
    wp_enqueue_script( 'builder-js', plugins_url( '/js/systembuilder.js', __FILE__ ));
}

add_action( 'wp_ajax_mriSearch', 'mriSearch' );   
add_action( 'wp_ajax_nopriv_mriSearch', 'mriSearch' );  


function mriSearch() {
    global $wpdb;

    $query = $_POST['query'];

    $result = "Running mriSearch";
    #$results = $wpdb->get_results( $wpdb->prepare($query, $inDate, $inMRILow, $inMRIHi) );
    echo json_encode($result, true);
    
    die();
}

and a Javascript file (systembuilder.js, in a folder named js under the plugin):

<script>
$(document).ready(function(){
    $('#MRISearchForm').submit(function(e){
        e.preventDefault();
        
        var form = $(this);
        var actionUrl = form.attr('action');
        
        $.ajax({
            type: "POST",
            url: actionUrl,
            data: form.serialize(),
            dataType: "json",
            success:function(data){
                // Process with the response data
                $('#search_results').html(data);
            }
        });
    });
});
</script>

And a form on a WordPress page:

<form type="post" action="/wp-admin/admin-ajax.php" role="form" id="MRISearchForm">
    <p style="font-size: 16pt;">Date: <input style="font-size: 16pt;" type="date" name="inDate" width="200" height="32"></p>
    <p style="font-size: 16pt;">Minimum MRI: <input style="font-size: 16pt;" type="number" name="inMRILow" value="70" min="0" max="100" width="200" height="32"></p>
    <p style="font-size: 16pt;">Maximum MRI: <input style="font-size: 16pt;" type="number" name="inMRIHi" value="100"  min="0" max="100" width="200" height="32"></p>
 
    
    <input type="hidden" name="action" value="mriSearch"/>
    <input type="submit" name="submit" value="Search" style="font-size: 18pt;">
    <input type="reset" style="font-size: 18pt;">
</form> 
<div id="search_results"></div>

I haven’t written any of the database query, etc. yet, just want to get this working first.

Submitting the form gives me a blank page with “Running mriSearch”. I can’t seem to get the scripts to update the “search_results” div, rather than just a blank page (url is ….com/wp-admin/admin-ajax.php?inDate=&inMRILow=70&inMRIHi=100&action=mriSearch&submit=Search).

I have tried to submit the form to my plugin php, I’ve tried it with the action empty, I’ve tried a million and one different things, and I’m sure that it’s something pretty simple.

Weird behavior when trying to use gemini API. How to make this javascript and html code properly work together?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Decision App</title>
<link rel="stylesheet" href="home_style.css">
</head>

<body class="base">
<h1>Decision App</h1>
<form id="task_form" method="post">            
<input type="text" id="task" name="task"><br><br>
<label for="task">Enter a task!:</label>
<input type="submit" id="submit" value="Submit">
</form>
<button id="google">Go to google</button>
<script type="module" src="task.js"></script>

<script type="importmap">
{
"imports": {
"@google/generative-ai": "https://esm.run/@google/generative-ai"
}
}
</script>
<script type="module">
// Fetch your API_KEY

    const API_KEY = "my key was here";
    import { GoogleGenerativeAI } from "@google/generative-ai";
    // Access your API key (see "Set up your API key" above)
    const genAI = new GoogleGenerativeAI(API_KEY);
    async function run() {
    // For text-only input, use the gemini-pro model
    const model = genAI.getGenerativeModel({ model: "gemini-pro"});

    const prompt = "Write a story about a magic backpack."

    const result = await model.generateContent(prompt);
    const response = await result.response;
    const text = response.text();
    console.log(text);
}

run();

</script>


</body>
</html>

When I try to do this using exact documentation from https://ai.google.dev/tutorials/get_started_web, I get the error “TypeError: Module name, ‘@google/generative-ai’ does not resolve to a valid URL.” In the console in my browser (safari). I am running the web server using “http-server c-1”. I’m practicing using javascript and trying to use gemini’s api. I even did npm install @google/generative-ai and it added a folder in the same directory everything is in. I tried to give all the details needed but I will happily give more details. As you can certainly tell I’m extremely new to js.

Why use the (this) for a method that already has context, and how to use arrow syntax

I have an issue.

I am learning JavaScript coding from a book I got and it is going pretty well. I went from not knowing anything at all to knowing how to store, modify and use data in about a week, and I am really happy with it; can’t wait to learn the other coding languages as well. There is one problem however, in this section of the book I learn about call(), apply(), and bind() methods. I know how call() works, calls a function with the context set as the value in the parameter, apply() I got confused on, and bind() I believe makes a new function which is a copy or reference to the one passed to the function within the parameters with the context of said argument, however, I am a little confused on it’s usage in this example in the book. In the method bookstore.displayBookstore at the very bottom, you will see shoppingCart.displayCart(this.removeBook.bind(this)) and I don’t truly understand why the bind method is run on removeBook if it is defined in the bookstore function already. Also how do you use arrow functions I really don’t understand.


    //Definition of the shoppingCart object
    const shoppingCart = { 
      itemsInCart: ['The Great Gatsby'], //Shopping Cart Items
      handleClick (removeBook) { 
        removeBook(this.itemsInCart)
      },
      // What to do when the 'Check Out' button is clicked ^
      displayCart(clickHandler) {
        const renderTarget = document.getElementById('Cart');
        const itemsInCart = this.itemsInCart.map ((item) => `<p>${item}</p>`);
        const checkoutButton = `<button id= 'checkout'>Check Out</button>`;
        renderTarget.innerHTML = itemsInCart.join('') + checkoutButton

        document.getElementById('checkout').addEventListener('click', () => this.handleClick(clickHandler));
        //display shoppingCart and Checkout Button
      },
    };
    //Definition of the bookstore object
    const bookstore = {
      books: ['Ulysses', 'The Great Gatsby'], //Books
      removeBook(title) {
        const newList = this.books.filter((book) => book != title);
        this.books = newList;
      },
      //method to remove a book from the books array
      displayBookstore(){
        const renderTarget = document.getElementById('bookstore');
        const bookList = this.books.map((book) => `<p>${book}</p>`);
        renderTarget.innerHTML = bookList.join('');

        shoppingCart.displayCart(this.removeBook.bind(this))
      },
      //method to display the books available.
    };

    bookstore.displayBookstore();

I like to write the code myself, tinker or try to understand what I am writing. I took the bind out of the function and hoped for it to still work, yet no luck, the console returned with ‘this.books is not defined’. So I now know that the bind() is required I just don’t know why, and before you ask, yes this is meant to be in an HTML document however I took it out and pasted this for simplicity sake, the document is not the issue. I completely apologized if the info is a little misplaced or hard to read, but any help is appreciated.

All the best,

M.

How to get the current price and time in TreadView based on X-axis and Y-axis

    widget.onChartReady(function () {
        widget.subscribe('mouse_up', function (params) {
            console.log('mouse_up:' + JSON.stringify(params));
            // params:{"clientX":1232,"clientY":488,"pageX":1232,"pageY":488,"screenX":1473,"screenY":599}
            // How to get the current price and time in TreadView based on X-axis and Y-axis.

使用widget.subscribe()打印出了{“clientX”:1452,”clientY”:613,”pageX”:1452,”pageY”:613,”screenX”:1693,”screenY”:724}我没有找到合适的方法来使用TreadingView转换成对应的时间和价格

Booking Mobile App cant show time on schedule as button grey



import React, {useState, useEffect} from 'react';
import {
  Text,
  View,
  StyleSheet,
  Dimensions,
  Image,
  ScrollView,
  FlatList,
  Alert,
  TouchableOpacity,
  TouchableWithoutFeedback,
} from 'react-native';
import {
  BORDERRADIUS,
  COLORS,
  FONTFAMILY,
  FONTSIZE,
  SPACING,
} from '../theme/theme';
import firestore from '@react-native-firebase/firestore';
import ScheduleCard from '../components/ScheduleCard';
import DateTimePicker from '@react-native-community/datetimepicker';
import moment from 'moment';
import CustomIcon from '../components/CustomIcon';

const windowHeight = Dimensions.get('window').height;
const windowWidth = Dimensions.get('window').width;

const ScheduleScreen = () => {
  const [fieldData, setFieldData] = useState([]);

  const fetchFieldData = async () => {
    try {
      const querySnapshot = await firestore()
        .collection('lapangan')
        .orderBy('created_at')
        .get();
      const data: any = querySnapshot.docs.map(doc => {
        const document = doc.data();
        document.id_lapangan = doc.id;
        document.image = document.image ? document.image : '';
        return document;
      });
      setFieldData(data);
    } catch (error) {
      console.log('Error fetching field data:', error);
    }
  };

  useEffect(() => {
    fetchFieldData();
  }, []);

  const [date, setDate] = useState(moment().tz('Asia/Singapore').toDate());
  const [showDatePicker, setShowDatePicker] = useState(false);
  const [bookingData, setBookingData] = useState([]);
  const availableTimes = [
    new Date(0, 0, 0, 10, 0, 0),
    new Date(0, 0, 0, 11, 0, 0),
    new Date(0, 0, 0, 12, 0, 0),
    new Date(0, 0, 0, 13, 0, 0),
    new Date(0, 0, 0, 14, 0, 0),
    new Date(0, 0, 0, 15, 0, 0),
    new Date(0, 0, 0, 16, 0, 0),
    new Date(0, 0, 0, 17, 0, 0),
    new Date(0, 0, 0, 18, 0, 0),
    new Date(0, 0, 0, 19, 0, 0),
    new Date(0, 0, 0, 20, 0, 0),
    new Date(0, 0, 0, 21, 0, 0),
    new Date(0, 0, 0, 22, 0, 0),
    new Date(0, 0, 0, 23, 0, 0),
  ];

  const handleDateChange = (event: any, selectedDate: any) => {
    const currentDate = selectedDate || date;
    setShowDatePicker(false);

    const selectedDateTime = moment(currentDate).tz('Asia/Singapore');
    const selectedDateOnly = selectedDateTime.format('YYYY-MM-DD');

    const today = moment().tz('Asia/Singapore');
    const normalizedCurrentDate = moment(selectedDateOnly).startOf('day');
    const normalizedToday = moment(today).tz('Asia/Singapore').startOf('day');

    if (normalizedCurrentDate.isBefore(normalizedToday)) {
      Alert.alert('Tanggal tidak valid', 'Tolong pilih tanggal yang valid');
      return;
    }

    setDate(selectedDateTime.toDate());
  };

  const [selectedTime, setSelectedTime] = useState(null);
  const [selectedFieldId, setSelectedFieldId] = useState(null);
  const handleImageClick = async (selectedFieldId: any) => {
    try {
      const querySnapshot = await firestore()
        .collection('booking')
        .where('id_lapangan', '==', selectedFieldId?.id_lapangan)
        .get();

      const bookings: any = querySnapshot.docs.map(doc => doc.data());

      setBookingData(bookings);
      setSelectedTime(null);

      console.log('Data booking :', bookings);
    } catch (error) {
      console.log('Error fetching booking data:', error);
    }
  };

  return (
    <ScrollView style={styles.container}>
      <View style={styles.wrapper}>
        <FlatList
          data={fieldData}
          showsHorizontalScrollIndicator={false}
          horizontal
          contentContainerStyle={styles.containerGap}
          renderItem={({item, index}) => (
            <ScheduleCard
              shouldMarginatedAtEnd={true}
              onPress={() => handleImageClick(item.id_lapangan)}
              cardWidth={windowWidth / 2}
              isFirst={index == 0 ? true : false}
              isLast={index === fieldData.length - 1}
              title={item.nama_lapangan}
              floor={item.lantai_lapangan}
              imagePath={item.image}
            />
          )}
        />
        <View style={styles.containerX}>
          <Text style={styles.dateInfoText}>Pilih Tanggal</Text>
          <TouchableOpacity
            style={styles.touchableInputX}
            onPress={() => setShowDatePicker(true)}>
            <Text style={styles.touchableInputTextX}>
              {moment(date)
                .tz('Asia/Singapore')
                .locale('id')
                .format('dddd, DD MMMM YYYY')}
            </Text>
          </TouchableOpacity>
          {showDatePicker && (
            <DateTimePicker
              value={moment(date).tz('Asia/Singapore').toDate()}
              mode="date"
              locale="id-ID"
              display="spinner"
              onChange={handleDateChange}
            />
          )}
        </View>
        <View style={styles.buttonContainer}>
          {Array.from(Array(4), (_, row) => (
            <View style={styles.row} key={`row_${row}`}>
              {Array.from(Array(row === 0 || row === 3 ? 3 : 4), (_, col) => {
                let index;
                if (row === 0) {
                  index = col;
                } else if (row === 1) {
                  index = 3 + col;
                } else if (row === 2) {
                  index = 7 + col;
                } else if (row === 3) {
                  index = 11 + col;
                }
                if (index < availableTimes.length) {
                  const time = availableTimes[index];
                  const isTimeBooked = bookingData.find(
                    booking =>
                      moment(booking.waktu).isSame(date) &&
                      moment(booking.waktu).hours() === time.getHours(),
                  );

                  return (
                    <TouchableWithoutFeedback
                      key={`button_${index}`}
                      onPress={() => setSelectedTime(time)}>
                      <View
                        style={[
                          styles.button,
                          isTimeBooked ? styles.buttonUnavailable : null, // Menambahkan kondisi untuk tampilan tombol yang sudah dipesan
                        ]}>
                        <Text style={styles.buttonText}>
                          {time.getHours()}:00
                        </Text>
                      </View>
                    </TouchableWithoutFeedback>
                  );
                } else {
                  return null;
                }
              })}
            </View>
          ))}
        </View>
        <View style={styles.timeRadioContainer}>
          <View style={styles.radioContainer}>
            <CustomIcon
              name="radio"
              style={[styles.radioIcon, {color: COLORS.Orange}]}
            />
            <Text style={styles.radioText}>Tersedia</Text>
          </View>
          <View style={styles.radioContainer}>
            <CustomIcon
              name="radio"
              style={[styles.radioIcon, {color: COLORS.Grey}]}
            />
            <Text style={styles.radioText}>Tidak Tersedia</Text>
          </View>
        </View>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    height: '100%',
    backgroundColor: COLORS.Black,
  },
  containerX: {
    flex: 1,
    justifyContent: 'center',
    position: 'relative',
    marginVertical: SPACING.space_16,
  },
  buttonContainer: {
    marginTop: SPACING.space_4,
    flexDirection: 'column',
    alignItems: 'center',
  },
  wrapper: {
    marginVertical: SPACING.space_32,
  },
  touchableInputX: {
    borderWidth: 2,
    borderColor: COLORS.White,
    backgroundColor: COLORS.Orange,
    borderRadius: BORDERRADIUS.radius_10,
    marginHorizontal: 40,
    paddingVertical: SPACING.space_10,
    fontSize: FONTSIZE.size_16,
    justifyContent: 'center',
  },
  touchableInputTextX: {
    fontFamily: FONTFAMILY.poppins_semibold,
    fontSize: FONTSIZE.size_16,
    color: COLORS.White,
    textAlign: 'center',
  },
  textHeader: {
    fontFamily: FONTFAMILY.poppins_semibold,
    fontSize: FONTSIZE.size_14,
    color: COLORS.White,
    paddingHorizontal: SPACING.space_36,
    paddingVertical: SPACING.space_32,
  },
  dateInfoText: {
    fontFamily: FONTFAMILY.poppins_regular,
    fontSize: FONTSIZE.size_14,
    color: COLORS.White,
    marginBottom: SPACING.space_4,
    marginLeft: SPACING.space_28,
  },
  containerGap: {
    gap: SPACING.space_36,
  },
  row: {
    flexDirection: 'row',
    marginBottom: 10,
  },
  button: {
    width: windowWidth * 0.18,
    height: 30,
    marginHorizontal: 5,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: BORDERRADIUS.radius_10,
    borderColor: COLORS.White,
    borderWidth: 2,
    backgroundColor: COLORS.Orange,
  },
  buttonUnavailable: {
    backgroundColor: COLORS.Grey,
  },
  buttonSelected: {
    backgroundColor: COLORS.White,
  },
  buttonText: {
    fontFamily: FONTFAMILY.poppins_semibold,
    fontSize: FONTSIZE.size_14,
    color: COLORS.White,
  },
  timeRadioContainer: {
    flexDirection: 'row',
    marginTop: SPACING.space_4,
    marginBottom: SPACING.space_10,
    alignItems: 'center',
    justifyContent: 'space-evenly',
  },
  radioContainer: {
    flexDirection: 'row',
    gap: SPACING.space_10,
    alignItems: 'center',
  },
  radioIcon: {
    fontSize: FONTSIZE.size_20,
    color: COLORS.White,
  },
  radioText: {
    fontFamily: FONTFAMILY.poppins_medium,
    fontSize: FONTSIZE.size_12,
    color: COLORS.White,
  },
});

export default ScheduleScreen;

i have 2 collection lapangan and booking

so after i clicked an image it get data id_lapangan from booking while id_lapangan data is lapangan document id.
my point is after i fetch data frm booking collection, choosing a date and the time on my app it didn’t change the touchablewithoutfeedback bgcolor from orange to grey.

how to make it right thank you.

Filtering out a key from a useState is causing the last element of ref object to null

I have a visuals state that contains a list of JSX visuals, and their corresponding references stored in a useRef object. I key into both of these with a ref “counter”. Currently in the useEffect, when pressed (a state) is true, I create the visual state and the visual ref along with it. Then the second part of the if statement runs after some time, which sets a timeout for 3 seconds, then deletes the corresponding visuals ref and state. The deletion of the ref works fine, and the state does too, correctly removing the visual by using filter so as to not mutate the state.

The problem is that filtering out the desired visual is setting the last ref in visual_refs to null. I have verified that it is the set_visuals() statement causing the problem, and also verified that the visual I need filtered out is not the one being set to null. If I comment out the deletion of the visual ref above the set_visuals(), the error still occurs

I have had this problem before when deleting a key from a state’s prev_state as I learned that this mutates the state, however filter + reduce should not. What is causing this and why?

let visual_refs = useRef([])
  let curr_animation = useRef([null, true])
  let [visuals, set_visuals] = useState({})
  let glowline = useRef(null)
 

  let counter = useRef(0)


  useEffect(() => {
    if (pressed) {
      audio.current.play()

      set_visuals(prev_state => {
        curr_animation.current[1] = true
        
        return ({
          ...prev_state,
          [counter.current]: (
          <div key={`${counter.current}`} ref={ref => visual_refs.current[counter.current] = ref} 
          className={`visualizer-instance ${color === 'black' ? 'black-visualizer': ''}  ${mp_pressed ? 'mp-visual': ''}`}></div>
          )
      })}) 
      
      attribute_animation(glowline.current, 'opacity', '0', '1', 600, 'cubic-bezier(0,.99,.26,.99)')

    } else if (!pressed && pressed !== null && counter.current in visual_refs.current && curr_animation.current[0]) {
        console.log(visual_refs.current, counter.current)
        curr_animation.current[0].pause()
        attribute_animation(visual_refs.current[counter.current], 'bottom', '0', '300000px', 1000000)
        attribute_animation(glowline.current, 'opacity', '1', '0', 3000, 'cubic-bezier(.19,.98,.24,1.01)')

        let curr_counter = counter.current
        setTimeout(() => {
          delete visual_refs.current[curr_counter]
          set_visuals(prev_state => {
            const new_state = Object.keys(prev_state).filter(key =>  key !== curr_counter.toString()).reduce((acc, key) => {
              acc[key] = prev_state[key]
              return acc
            }, {})
            return new_state
          })
        }, 3000, curr_counter)
          
        counter.current += 1
    }
  }, [pressed])

How to load a map like this site: https://genshin.gamedot.org/?mid=genshinmaps, in Leaflet?

The site: https://genshin.gamedot.org/?mid=genshinmaps

I built a site where I can move an imageOverlay map around and zoom to explore, but I want to load the map into several pieces this time, like what that site does, and what Google Maps does.

I simply tried to use tileLayer to reproduce this, but I found that there are large difference.

The site still loads the image with multiple tiles at its min zoom level. For Leaflet, it load only one image when it is at its min level of 0. Moreover, as I zoom in, the position of tiles gets weird and I can only see limited number of tiles in the border. I think this is because my understanding of tileLayer is weak, but it is true that I cannot get a satisfying result even with GPT.

The site keeps using 256256 tile for every zoom level, but the content and the number of tiles needed to make the entire map changes when the map is zoomed. This was similar in Leaflet tileLayer, but I have no idea how I need to cut the source image in based on its zoom level. First, I just cut the image into a bunch of 256256 tiles, but then what’s next? How do I cut the image for the next zoom level? For now, I have no idea..

I don’t think the site uses Leaflet, but if I can, I wanna know what feature does the site uses to load the map with tiles.

I have a problem where the CardUpdateFile component does not appear on the screen. REACT JS

After I upload a file with handleSubsitSubsidList, showCardUpdateFile becomes true and listSubsidyData gets the date after upload (At least that’s the idea ) but the Card never appears on the screen if I do a test setting showCardUpdateFile to true and remove the validations {showCardUpdateFile && listSubsidyData && it appears so the problem is not in the card component.

Im new to coding.

Father Component

function SubsidyForm() {
  const [isModalOpen, setIsModalOpen] = useState(false)
  const [isAddDiscountListModalOpen, setIsAddDiscountListModalOpen] = useState(false)
  const handleOpenModal = () => setIsModalOpen(true)
  const handleCloseModal = () => setIsModalOpen(false)
  const openAddDiscountListModal = () => setIsAddDiscountListModalOpen(true)
  const closeAddDiscountListModal = () => setIsAddDiscountListModalOpen(false)
  return (
    <Card>
      <CardHeader>
        <h2>Subsídio</h2>
      </CardHeader>

      <SimpleDetailsCardContent>
        <Row>
          <Col sm={2}>
            <CardField label="Regras modelos e receitas" value="valor XPTO" />
          </Col>
        </Row>
        <Row mb={'1rem'} mt="1rem">
          <Col sm={2}>
            <CardField label="CRM" value="valor XYZ" />
          </Col>
        </Row>
        <CoveredProductsForm />
      </SimpleDetailsCardContent>
    </Card>
  )
}
export default SubsidyForm

COMPONENT CoveredProductForm.tsx

  function CoveredProductsForm() {
  const [showEmptyScreen, setShowEmptyScreen] = useState(false)
  const [isUploading, setIsUploading] = useState(false)
  const [currentModal, setCurrentModal] = useState<ModalType>()
  const [listDiscountData, setListDiscountData] =
    useState<ListDiscountPlanHistoricalModal | null>(null)
  const [listSubsidyData, setListSubsidyData] =
    useState<ListSubsidyPlanHistoricalModal | null>(null)
  const [showCardUpdateFile, setShowCardUpdateFile] = useState(false)

  const [selectedSubsidy, setSelectedSubsidy] = useState('')
  const [referenceNumber, setReferenceNumber] = useState('')
  const [similarNumber, setSimilarNumber] = useState('')
  const [genericNumber, setGenericNumber] = useState('')
  const [contractId, setContractId] = useState<number>(0)
  const [productId, setProductId] = useState<number>(0)
  const [planId, setPlanId] = useState<number>(0)

 const handleModalOpen = (modalName: ModalType) => {
    setCurrentModal(modalName)
  }

  const handleModalClose = () => {
    setCurrentModal(undefined)
  }
 const onListSubmitSuccess = useCallback(
    (data: React.SetStateAction<ListSubsidyPlanHistoricalModal | null>) => {
      console.log('Upload successful with data:', data)
      if (data) {
        setListSubsidyData(data)
        setShowCardUpdateFile(true)
      } else {
        console.error('No data received in onListSubmitSuccess')
      }
    },
    []
  )
 const handleModalSubmit = (data: CoveredProductsFormData) => {
    console.log('Handling upload success with data:', data)

    setSelectedSubsidy(data.subsidyDeterminedBy)
    if (data.subsidyDeterminedBy === 'Tipo de Produto') {
      setReferenceNumber(data.referenceNumber?.toString() || '')
      setSimilarNumber(data.similarNumber?.toString() || '')
      setGenericNumber(data.genericNumber?.toString() || '')
    }
    setCurrentModal(undefined)
  }
  useEffect(() => {
    console.log('Updated listSubsidyData (in useEffect):', listSubsidyData)
    console.log('showCardUpdateFile (in useEffect):', showCardUpdateFile)
  }, [listSubsidyData, showCardUpdateFile])

  useEffect(() => {
    if (listDiscountData) {
      setShowCardUpdateFile(true)
    } else {
      setShowCardUpdateFile(false)
    }
  }, [listDiscountData])


return (
    <>
      {showEmptyScreen && <EmptyCoveredProducts onAdd={onConfigureNow} />}

      {!showEmptyScreen && (
        <>
          <S.HeaderSubgroup>
            <h2>Produtos Contemplados</h2>
            <Button id="edit-products" onClick={handleEditModalOpen}>
              <Image src={EditIcon} alt="Editar" />
            </Button>
          </S.HeaderSubgroup>
          <SimpleDetailsCardContent
            style={{
              backgroundColor: '#f3f3f3',
              borderRadius: '8px',
              display: 'flex',
              flexDirection: 'column',
            }}
          >
            <Row>
              <Col sm={2}>
                <CardField
                  label="Subsídio determinado por"
                  value={selectedSubsidy || 'Escolha uma opção'}
                />
              </Col>
              {selectedSubsidy === 'Tipo de Produto' && (
                <>
                  <Col sm={2}>
                    <CardField label="% Referência" value={referenceNumber + '%'} />
                  </Col>
                  <Col sm={2}>
                    <CardField label="% Similar" value={similarNumber + '%'} />
                  </Col>
                  <Col sm={2}>
                    <CardField label="% Genérico" value={genericNumber + '%'} />
                  </Col>
                </>
              )}
            </Row>
          </SimpleDetailsCardContent>
          {showCardUpdateFile && listSubsidyData && (
            <CardUpdateFile
              allowDelete={true}
              listDiscount={listSubsidyData}
              onClickDelete={() => {
                setListSubsidyData(null)
                setShowCardUpdateFile(false)
              }}
              onClickViewFile={() => console.log('Visualizar arquivo')}
              onClickReplaceFile={() => console.log('Substituir arquivo')}
              submitId="unique-submit-id"
              editId="unique-edit-id"
              onClickSubmit={() => console.log('Submetido')}
            />
          )}
          <ProductsCoveredModal
            isOpen={currentModal === 'productsCovered'}
            onCloseModal={() => handleModalClose()}
            onSubmit={data => handleModalSubmit(data)}
            defaultValues={{ subsidyDeterminedBy: 'Lista de Produto' }}
            onListSubmitSuccess={(
              data: React.SetStateAction<ListSubsidyPlanHistoricalModal | null>
            ) => onListSubmitSuccess(data)}
          />
        </>
      )}
    </>
  )
}

export default CoveredProductsForm


COMPONENT ProductCoveredModal


const nrVersion = 1

export interface SubsidyListFormData {
  allowsDiscountList: number
  subsidyListTypeName?: string
  effectiveDate?: Date
  endEffectiveDate?: Date
  hasValidity?: number
}
interface ListSubsidyPlanHistoricalModal {
  contractId: number
  nrVersion: number
  productId: number
  planId: number
  listId: number
  operatorId: string
  registerDate: Date
}

export interface CoveredProductsFormData {
  subsidyDeterminedBy: 'Tipo de Produto' | 'Lista de Produto'
  referenceNumber?: number
  similarNumber?: number
  genericNumber?: number
}

interface ProductsCoveredModalProps {
  isOpen: boolean
  defaultValues: CoveredProductsFormData
  onCloseModal: () => void
  onSubmit: (data: CoveredProductsFormData) => void
  onUploadSuccess?: (data: any) => void
  onListSubmitSuccess: (data: ListSubsidyPlanHistoricalModal) => void

function ProductsCoveredModal({
  isOpen,
  defaultValues,
  onCloseModal,
  onSubmit,
  onListSubmitSuccess,
}: ProductsCoveredModalProps): React.ReactElement {
  const [haveSubsidyInferiorThan100, setHaveSubsidyInferiorThan100] = useState(true) // TODO Para Futura regra de negocio em Sobre Pagamento Beneficiario
  const schema = React.useMemo(
    () => getSchema(haveSubsidyInferiorThan100),
    [haveSubsidyInferiorThan100]
  )
  const {
    handleSubmit,
    control,
    formState: { errors },
    watch,
    register,
  } = useForm<CoveredProductsFormData>({
    resolver: zodResolver(schema),
    defaultValues: {
      ...defaultValues,
      subsidyDeterminedBy: 'Tipo de Produto',
    },
  })
}
 useEffect(() => {
    setIds({
      contractId: Number(router.query.idContrato || 0),
      productId: Number(router.query.produtoId || 0),
      planId: Number(router.query.planoId || 0),
    })
  }, [router.query])

const [listSubsidyData, setListSubsidyData] =
    useState<ListSubsidyPlanHistoricalModal | null>(null)

  const subsidyDeterminedByValue = watch('subsidyDeterminedBy')

const handleSubmitSubsidyList = useCallback(
    async (file: File) => {
      setIsUploading(true)
      const formData = new FormData()
      formData.append('file', file)
      formData.append('operator-id', '1')

      try {
        const result = await subsidyService.uploadSubsidyList(
          contractId,
          productId,
          planId,
          nrVersion,
          formData
        )
        console.log('Upload result:', result)

        if (!Array.isArray(result) && result.listId) {
          const listData: ListSubsidyPlanHistoricalModal = {
            contractId: result.contractId,
            nrVersion: result.nrVersion,
            productId: result.productId,
            planId: result.planId,
            listId: result.listId,
            operatorId: result.operatorId,
            registerDate: new Date(result.registerDate),
          }

          onListSubmitSuccess(listData)
          setListSubsidyData(listData)

          setShowCardUpdateFile(true)
        } else {
          modalDispatch({
            type: 'ERROR',
            message: 'Ocorreu um erro ao fazer upload da lista de subsídios.',
          })
        }
      } catch (error) {
        console.error('Erro ao fazer upload da lista de subsídios:', error)
        modalDispatch({
          type: 'ERROR',
          message: 'Ocorreu um erro inesperado ao fazer upload da lista de subsídios.',
        })
      } finally {
        setIsUploading(false)
      }
    },
    [
      subsidyService,
      contractId,
      productId,
      planId,
      nrVersion,
      modalDispatch,
      onListSubmitSuccess,
    ]
 useEffect(() => {
    if (listSubsidyData) {
      setShowCardUpdateFile(true)
    }
  }, [listSubsidyData])
  )



const handleOnUploadDiscountList = useCallback(
    async (file: File) => {
      setIsUploading(true)
      try {
        const result = await handleSubmitSubsidyList(file)
      } catch (error) {
        console.error('Erro ao fazer upload da lista de subsídios:', error)
      } finally {
        setIsUploading(false)
      }
    },
    [handleSubmitSubsidyList]
  )
const handleModalSubmit = async (data: CoveredProductsFormData) => {
    if (data.subsidyDeterminedBy === 'Tipo de Produto') {
      const subsidyData = {
        pcGeneric: data.genericNumber ?? 0,
        pcReference: data.referenceNumber ?? 0,
        pcSimilar: data.similarNumber ?? 0,
      }

      try {
        await productsService.updateSubsidyProductType(
          ids.contractId,
          ids.productId,
          ids.planId,
          nrVersion,
          subsidyData
        )

        console.log('Subsídio atualizado com sucesso')
        onSubmit(data)
        onCloseModal()
      } catch (error) {
        console.error('Erro ao atualizar o subsídio:', error)
      }
    } else if (data.subsidyDeterminedBy === 'Lista de Produto') {
      setShowAddSubsidyListModal(true)
    }
  }
  return (
    <Modal.Container isOpen={isOpen} w="80rem" closeModal={onCloseModal}>
      <Modal.Header title="Produtos Contemplados" />
      <Modal.Content>
        <Form onSubmit={handleSubmit(handleModalSubmit)} id="formProductsCovered">
          <Row mb="2rem">
            <Col sm={4}>
              <Controller
                name="subsidyDeterminedBy"
                control={control}
                render={({ field }) => (
                  <TextField {...field} fullWidth select label="Subsídio determinado por">
                    <MenuItem value="Tipo de Produto">Tipo de Produto</MenuItem>
                    <MenuItem value="Lista de Produto">Lista de Produto</MenuItem>
                  </TextField>
                )}
              />
            </Col>

            {subsidyDeterminedByValue === 'Tipo de Produto' && (
              <>
                <Col sm={2}>
                  <TextField
                    type="number"
                    fullWidth
                    label="Referência"
                    {...register('referenceNumber')}
                    error={!!errors.referenceNumber}
                    helperText={errors.referenceNumber?.message}
                  />
                </Col>
                <Col sm={2}>
                  <TextField
                    type="number"
                    fullWidth
                    label="Similar"
                    {...register('similarNumber')}
                    error={!!errors.similarNumber}
                    helperText={errors.similarNumber?.message}
                  />
                </Col>
                <Col sm={2}>
                  <TextField
                    type="number"
                    fullWidth
                    label="Genérico"
                    {...register('genericNumber')}
                    error={!!errors.genericNumber}
                    helperText={errors.genericNumber?.message}
                  />
                </Col>
              </>
            )}
            {showAddSubsidyListModal && (
              <AddSubsidyListModal
                planId={ids.planId}
                productId={ids.productId}
                contractCode={ids.contractId}
                isOpen={showAddSubsidyListModal}
                isDeleteOpen={false}
                isUploading={isUploading}
                wannaChange={false}
                onUploadDiscountList={async (file: File) => {
                  await handleOnUploadDiscountList(file)
                  onListSubmitSuccess
                }}
                closeModal={() => {
                  setIsModalAddSubsidyOpen(false)
                  setShowAddSubsidyListModal(false)
                }}
                onCancel={() => {
                  setIsModalAddSubsidyOpen(false)
                  setShowAddSubsidyListModal(false)
                }}
                onDeleteClose={() => {
                  setIsModalAddSubsidyOpen(false)
                  setShowAddSubsidyListModal(false)
                }}
                onListDeleted={function (): void {
                  throw new Error('Function not implemented.')
                }}
              />
            )}
          </Row>
          <Modal.Footer>
            <Button
              id="edit-list-CoveredProducts-cancel"
              onClick={onCloseModal}
              styleType="secondary"
              type="button"
            >
              cancelar
            </Button>
            <Button
              id="edit-list-CoveredProducts-submit"
              styleType="primary"
              type="submit"
            >
              salvar
            </Button>
          </Modal.Footer>
        </Form>
      </Modal.Content>
    </Modal.Container>
  )
}

export default ProductsCoveredModal

Requisicao

import { DiscountListDataRequestBody } from '@/domain/interface/Planner.model'
import AxiosHttpService from './AxiosHttpService'
import { EndpointsConstraints } from './endpointsConstraints'
import { AxiosError } from 'axios'
export interface UploadResponse {
  contractId: number
  nrVersion: number
  productId: number
  planId: number
  listId: number
  operatorId: string
  registerDate: string
}
export default class CoveredProductService extends AxiosHttpService {
  private handleSubsidyListUploadError(ex: AxiosError) {
    const errorResponse = (ex as any)?.response?.data?.problemDescription

    if (!errorResponse) {
      return ['Arquivo inválido.']
    }

    if (errorResponse.userMessage) {
      return [errorResponse.userMessage as string]
    }

    try {
      const { errorsInput } = JSON.parse(errorResponse.detail)

      const errors: string[] = []
      for (const error of errorsInput) {
        errors.push(...error.errorsDescriptions)
      }

      return errors
    } catch {
      return ['Arquivo inválido.']
    }
  }
  async uploadSubsidyList(
    contractId: number,
    productId: number,
    planId: number,
    version: number,
    formData: FormData
  ): Promise<UploadResponse | string[]> {
    const url = EndpointsConstraints.UPLOAD_SUBSIDY_LIST_HIST(
      contractId,
      productId,
      planId,
      version
    )

    try {
      const response = await this.put<UploadResponse>(url, formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
        skipErrorHandler: true,
      })

      return response.data
    } catch (ex) {
      const errors: string[] = this.handleSubsidyListUploadError(ex as AxiosError)
      return errors
    }
  }
}

I just need that the component CardUpdateFile, shows in the screen when i upload a file successfully.

Drag and drop event propagation

I’m attempting to setup drag and drop in my project

I’ve got several fields setup like this
enter image description here
If a user clicks the image on the left and drags, they can re-order the rows

When a valid dropzone is detected (in this case, any other row is a valid dropzone) a class is applied to the div wrapping all elements of that row which renders a border underneath to indicate where the dropped row will be inserted
enter image description here

My problem is, for some reason, if I drag a row over one of the input or select elements that are a child of the dropzone, they are concidered to be the dropzone rather than the underlying element.
enter image description here
Its a little hard to see but theres a dashed line under the right most input indicating my dropzone class has been added.

How its setup

The following JS is called for each valid dropzone

function dropzone(node, options) {
  console.log(`created dropzone on ${node}`);
  let state = {
    dropEffect: "move",
    dragover_class: ["dropzone", "pb-3"],
    ...options,
  };

  function handle_dragenter(e) {
    console.log(`DragEnter ${e.target}`);
    e.stopPropagation();
    e.target.classList.add(...state.dragover_class);
  }

  function handle_dragleave(e) {
    console.log(`DragLeave ${e.target}`);
    e.stopPropagation();
    e.target.classList.remove(...state.dragover_class);
  }

  function handle_dragover(e) {
    console.log(`DragOver ${e.target}`);
    e.stopPropagation();
    e.dataTransfer.dropEffect = state.dropEffect;
  }

  node.addEventListener("dragenter", handle_dragenter, true);
  node.addEventListener("dragleave", handle_dragleave, true);
  node.addEventListener("dragover", handle_dragover, true);
}

What I’ve tried

CSS

I’ve tried adding pointer-events: none; to all children of my dropzone class thats added in my dragenter handler which works but only when the dropzone is successfully entered before any of its children. I’ve also tried blanked setting pointer-events: none; on all child elements of dropzones which does fix the issue but it also prevents the inputs from working

JS

I’ve tried setting useCapture to true when adding my event listeners via addEventListener and calling e.stopPropagation() inside all of my handlers which to my understanding should cause the node the event listener is added to (in this case, the dropzone row) to be called first before propogating down to all children. However, the inputs are still receiving dragenter events

useCapture feels like the most promising approach but I must me missing something here (or it doesnt work on drag events for some reason).

Can anyone see anything obviously wrong with my setup or provide me with any other suggestions to fix my issue?

How to use JavaScript in WordPress [closed]

I’m new to WordPress and am currently working on porting an existing website over to WordPress. In the current website there is a javascript that is called when a user clicks a link. This then calls a javascript function that takes two variables. This is what the current website snippet of code looks like:

href=”#” onclick=”javascript:ridepassWord(’email address here’, ’email subject here’)” target=”_top”>Click here to sign up for this trip

The javascript will then prompt for and verify a password before an email is sent. I’ve been trying to figure out how to implement this in WordPress but so far have failed to figure out how to implement this JavaScript or to find an alternate means to achieve this in WordPress.

I’ve tried a couple of plugins to implement the JavaScript but have not figured how to to call the javascript when the link is clicked.

how to share one state in different components without knowing the parent React

consider i have a Component called Button it return new button with a state which could be active or not when activated some styling are applied to it

know this Button is an exportable Component it can be used in any place in the project
but i want only one to be active in any time

function Button({startActive,number}) { 
  let [active, setActive] = useState(startActive ?? false)

  return <button className={`${active ? 'active' : ''}`} onClick={_ => setActive(!active)} >{number}</button>
}

function App() {
  return (<>
    <Button startActive={true} number={1} />
    <Button number={2} />
    <Button number={3} />
  </>)
}

now all this code doing is create there buttons the first is active and when i click on one of theme it toggle it

how i can make it remove the active state from all other button

note: don’t use the component App if you can i want to be able to use the component Button any where without adding extra states to the parent

sorry if it’s easy question I’m new to react

How to disable v-autocomplete events for appended icon click

I have a autocomplete input with an appended inner icon that has a click function attached and then clearable is enabled. If you click clearable the options menu appears and if you click the appended icon the options menu also appears. I do not want these icons to initiate the options menu since a user would not click them and click elsewhere to enable the options. This is my code below. How do I disable the option event for these icons?

<v-autocomplete
                      v-for="(header,index) in headers"
                      :key="index"
                      v-model="header.filtered"
                      class="my-5"
                      clearable
                      chips
                      :label="header.title"
                      :items="getUniqueList(displayedReviews,header.key)"
                      multiple
                      density="compact"
                      variant="outlined"
                      hide-details
                      single-line
                      flat
                      @blur="applyFilters()"
                      :append-inner-icon="header.visible ? 'mdi-eye' : 'mdi-eye-off'"
                      @click:append-inner="header.visible = !header.visible"
                    >
                    </v-autocomplete>