• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
    • Questions
    • Teachers
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

262
Views
Vue: haga que la parte coincidente de la entrada esté en negrita, incluidos los guiones especiales

He creado un componente de selección simple en Vue con un sistema de búsqueda/filtro. Basado en la entrada del usuario, muestro algunas sugerencias de ciudades de Bélgica.

Ejemplo de trabajo: https://codesandbox.io/s/wandering-lake-lecok?file=/src/components/Select.vue (A veces hay un mensaje de error en Codesandbox. Actualice la compilación en el navegador y debería funcionar)

Quiero llevar la UX un paso más allá y mostrar la parte correspondiente de la entrada del usuario en negrita y subrayada. Por lo tanto, tengo una función makeBold funcionamiento. Al dividir la cadena de sugerencias en varias partes, puedo agregar una etiqueta en negrita y subrayada y devolver la sugerencia.

 computed: { results() { return this.options.filter((option) => option.display_name .replaceAll("-'", "") .toLowerCase() .includes(this.searchInput.replaceAll("-'", "").toLowerCase()) ); }, }, methods: { makeBold(str, query) { const n = str.toUpperCase(); const q = query.toUpperCase(); const x = n.indexOf(q); if (!q || x === -1) { return str; } const l = q.length; return ( str.substr(0, x) + "<b><u>" + str.substr(x, l) + "</u></b>" + str.substr(x + l) ); }, }

Un problema, muchas ciudades en Bélgica usan guiones y/o apóstrofes. En la función de sugerencias, elimino estos caracteres para que el usuario no tenga que escribirlos. Pero en la función makeBold me gustaría poner estos caracteres en negrita y subrayados.

Por ejemplo:

Cuando la entrada es 'sint j', 'sintj' o 'Sint-j', quiero que las sugerencias se vean como ' Sint-J ans-Molenbeek' y ' Sint-J ob in't Goor'

¿Hay alguien que pueda darme un desglose de cómo lograr esto?

almost 3 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Una forma es transformar su cadena de búsqueda en un objeto RegExp y usar la sobrecarga de cadena replace(regexp, replacerFunction) para lograrlo.
Por ejemplo, la cadena de búsqueda es "sintg"

 new RegExp(this.searchInput.split("").join("-?"), "i");

Lo convierte en /s-?i-?n-?t-?g/gi
-? indica opcional - carácter y
"i" al final es el indicador que no distingue entre mayúsculas y minúsculas RegExp

Aplicado al código de codesandbox obtienes esto

 computed: { results() { const regex = new RegExp(this.searchInput.split("").join("-?"), "i"); return this.options.filter((option) => option.display_name.match(regex)); }, }, methods: { makeBold(str, query) { const regex = new RegExp(query.split("").join("-?"), "i"); return str.replace(regex, (match) => "<b><u>" + match + "</u></b>"); }, },

Lo que da este resultado

ingrese la descripción de la imagen aquí

Sin embargo, hay una advertencia: se generarán errores si el usuario coloca un símbolo especial RegExp en el cuadro de búsqueda.
Para evitar esto, el texto de entrada de búsqueda inicial debe aplicar el escape RegExp.
Como:

 new RegExp(escapeRegExp(this.searchInput).split("").join("-?"), "i");

Pero no existe un método nativo escapeRegExp .
Puede encontrar uno en la cadena Escape para usar en Javascript regex
También hay una función escapeRegExp en la biblioteca lodash si ya está en su lista de dependencias (le evita agregar otra función)

almost 3 years ago · Juan Pablo Isaza Report

0

Propondría usar una máscara, para guardar la estructura del nombre de la ciudad, y después de encontrar el índice inicial y final de la subcadena en el nombre de la ciudad, restaurar la cadena original de la máscara, insertando las etiquetas apropiadas en el índice inicial y final usando una función de reemplazo. . de esta manera, no se preocupará por ningún otro carácter que no sea una palabra u otra entrada inesperada del usuario.

Aquí está la función makeBold:

 makeBold(str, query) { // mask all word characters in city name const city_mask = str.replace(/\w/g, "#"); // strip city and query string from any non-word character let query_stripped = query.toLowerCase().replace(/\W/g, ""); let string_stripped = str.replace(/\W/g, ""); // find the index of querystring in city name let index = string_stripped.toLowerCase().indexOf(query_stripped); if (index > -1 && query_stripped.length) { // find the end position of substring in stripped city name let end_index = index + query_stripped.length - 1; // replacer function for each masked character. // it will add to the start and end character of substring the corresponding tags, // replacing all masked characters with the original one. function replacer(i) { let repl = string_stripped[i]; if (i === index) { repl = "<b><u>" + repl; } if (i === end_index) { repl = repl + "</u></b>"; } return repl; } let i = -1; // restore masked string return city_mask.replace(/#/g, (_) => { i++; return replacer(i); }); } return str; }

Y aquí está la caja de arena de trabajo. Cambié un poco los results calculados para eliminar todos los caracteres que no son palabras.

almost 3 years ago · Juan Pablo Isaza Report

0

Podría crear una función que elimine todos los spaces y - en la cadena de consulta y ciudad. Si la ciudad incluye la consulta, divida la cadena de consulta en la última letra y obtenga las apariciones de esa letra en la consulta. Calcule la longitud para cortar y devuelva la parte correspondiente de la cadena de ciudad original.

 const findMatch = (q, c) => { const query = q.toLowerCase().replace(/[\s-]/g, ""); const city = c.toLowerCase().replace(/[\s-]/g, ""); if (city.includes(query)) { const last = query.charAt(query.length - 1); // last letter const occ = query.split(last).length - 1; // get occurences // calculate slice length const len = c.toLowerCase().split(last, occ).join(" ").length + 1; return c.slice(0, len); } return "No matching city found." } const city = "Sint-Jan Test"; console.log(findMatch("sint j", city)); console.log(findMatch("sintj", city)); console.log(findMatch("Sint Jan t", city)); console.log(findMatch("sint-j", city)); console.log(findMatch("Sint-J", city)); console.log(findMatch("SintJan te", city));

almost 3 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error