Je construis une chaîne de requête en Javascript selon qu'une case à cocher est cochée ou non.

Certaines des options dans les cases à cocher sont

  • "Annuel"
  • "Herbe"
  • "Arbuste (à feuilles persistantes)"
  • "Arbuste (à feuilles caduques)"

J'ai trouvé une fonction en ligne qui met à jour le paramètre url :

function updateUrlParameter(uri, key, value) {
  value = value.replace(/\s/g, "%20");
  var i = uri.indexOf('#');
  var hash = i === -1 ? '' : uri.substr(i);
  uri = i === -1 ? uri : uri.substr(0, i);
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";

  if (!value) {
    // remove key-value pair if value is empty
    uri = uri.replace(new RegExp("([&]?)" + key + "=.*?(&|$)", "i"), '');
    if (uri.slice(-1) === '?') {
        uri = uri.slice(0, -1);
    }
  } else {
    console.log("value is " + value)
    uri = uri + separator + key + "=" + value;
  }
  return uri + hash;
}

En utilisant la fonction ci-dessus, si je coche les cases des quatre ci-dessus en commençant de haut en bas, ma chaîne de requête devient

?plantType=Annual&plantType=Grass&plantType=Shrub%20(Evergreen)&plantType=Shrub%20(Deciduous

Pourquoi la fonction ignore-t-elle le dernier ')' de la chaîne ? Y a-t-il un travail autour de cela? Je voudrais conserver la parenthèse dans la chaîne de requête car cela facilitera l'interrogation de la base de données.

J'ai créé une fonction pour parcourir les cases à cocher d'entrée. S'ils sont cochés, utilisez la fonction updateUrlParameter pour mettre à jour l'URI.

function getQueryString() {
  var inputsContainerChildren = $('#floatingDivForFilter').children();
  var input = document.createElement('input')
  var uri = '';

  for (var i = 0; i < inputsContainerChildren.length; i++) {
    var currChild = inputsContainerChildren[i].firstElementChild;
    if (currChild) {
        if (currChild.tagName === 'INPUT') {
            if (currChild.checked) {
                var id = currChild.id;
                    console.log(uri)
                    uri  = updateUrlParameter(uri, currChild.name, currChild.value);
            }
        }
    }
} 
console.log(uri);

}

La photo ci-dessous montre un instantané de l'URL produite. Je ne peux pas comprendre pourquoi le dernier ')' est coupé. url photo

0
hello 7 mars 2019 à 20:55

2 réponses

Meilleure réponse

Le problème que vous voyez est juste les outils de développement Chrome qui essaient d'être trop intelligents.

Lors de la connexion de l'URL à la console, Chrome ne reconnaîtra pas l'URL complète en tant que lien mais exclura la fermeture ")". Ils le font probablement parce qu'il sera très courant que les gens écrivent une URL entre accolades et on ne s'attend pas à ce que l'accolade fermante fasse partie de l'URL.

Comme il ne s'agit que d'un problème des outils de développement, vous pouvez ignorer le problème. Cela n'affectera pas le comportement d'exécution de votre code.

Le problème sera résolu lorsque vous échapperez correctement les caractères spéciaux dans les paramètres (comme vous devriez le faire de toute façon):

function updateUrlParameter(uri, key, value) {
  // removed because escape will do that 
  // value = value.replace(/\s/g, "%20");
  var i = uri.indexOf('#');
  var hash = i === -1 ? '' : uri.substr(i);
  uri = i === -1 ? uri : uri.substr(0, i);
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";

  if (!value) {
    // remove key-value pair if value is empty
    uri = uri.replace(new RegExp("([&]?)" + key + "=.*?(&|$)", "i"), '');
    if (uri.slice(-1) === '?') {
        uri = uri.slice(0, -1);
    }
  } else {
    console.log("value is " + value)
    // Use escape on key and value
    uri = uri + separator + escape(key) + "=" + escape(value);
  }
  return uri + hash;
}

let s = "http://chrome.is.too.clever/";
s = updateUrlParameter(s, "plantType", "Annual");
s = updateUrlParameter(s, "plantType", "Grass");
s = updateUrlParameter(s, "plantType", "Shrub (Evergreen)");
s = updateUrlParameter(s, "plantType", "Shrub (Deciduous)");
console.log(s);

Violon

0
NineBerry 7 mars 2019 à 18:49

Au lieu d'utiliser une expression régulière, convertissez simplement les paramètres en un objet, modifiez cet objet et reconvertissez-le en paramètres.

var url = 'https://x.y?plantType=Annual&plantType=Grass&plantType=Shrub%20(Evergreen)&plantType=Shrub%20(Deciduous)';

function updateUrlParameter(uri, key, value) {
  let url = new URL(uri), object = deserializeQuery(url.search); // params to obj
  object[key] = value; // modify obj
  return url.origin + '?' + serializeQuery(object); // obj to url + params
}

console.log(updateUrlParameter(url, 'plantType', [ 'Pine', 'Palm', 'Rose (Red)' ]));

/** ======= Serialization / Deserialization functions below ======== */

// https://stackoverflow.com/a/47517503/1762224
function deserializeQuery(queryString, queryKey) {
  let query = {}, pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
  for (var i = 0; i < pairs.length; i++) {
    var pair = pairs[i].split('='), key = decodeURIComponent(pair[0]), value = decodeURIComponent(pair[1] || '');
    value = (value.indexOf(',') === -1 ? value : value.split(','));
    query[key] = query[key] ? (query[key].constructor === Array ? query[key].concat(value) : [query[key], value]) : value;
  }
  return typeof queryKey === 'undefined' ? query : query[queryKey];
}

// https://stackoverflow.com/a/53528203/1762224
function serializeQuery(params, keys = [], isArray = false) {
  const p = Object.keys(params).map(key => {
    let val = params[key];
    if ("[object Object]" === Object.prototype.toString.call(val) || Array.isArray(val)) {
      keys.push(Array.isArray(params) ? "" : key);
      return serializeQuery(val, keys, Array.isArray(val));
    } else {
      let tKey = keys.length > 0 ? ((isArray ? keys : [...keys, key]).reduce((str, k) => "" === str ? k : `${str}[${k}]`, "")) : key;
      if (isArray) {
        return encodeURIComponent(tKey) + '=' + encodeURIComponent(val);
      }
    }
  }).join('&');
  keys.pop();
  return p;
}
.as-console-wrapper {
  top: 0;
  max-height: 100% !important;
}

.as-console-row {
  white-space: pre-wrap;
  word-break: break-all;
}
0
Mr. Polywhirl 7 mars 2019 à 18:50