web-dev-qa-db-fra.com

Prettify json data en entrée textarea

J'ai cherché ce sujet en particulier et je n'ai rien trouvé de semblable. S'il y en a, fermez-le et donnez un lien.

Je crée un simulateur json data api. Je souhaite que les utilisateurs puissent copier et coller une demande d'objet JSON dans une zone de texte où ils peuvent également la modifier avant de l'envoyer au serveur. 

Le problème est json obj copy et les tapotements entraînent souvent des espaces supplémentaires et ne sont jamais alignés correctement, même avec la balise pre. Je veux aussi un bon jeu de couleurs appliqué aux clés et aux valeurs.

J'ai vu des plugins, d'autres questions et des extraits de code, mais ils ne s'appliquent pas aux zones de texte où le texte est éditable. Est-il possible de conserver son style en mode édition sans afficher toutes les balises HTML qui l'ont stylé? Je veux pouvoir l'écrire à partir de zéro avec javascript ou jquery.

24
archytect

La coloration syntaxique est difficile, mais jetez un œil à ce fiddle pour une jolie impression d’un objet json entré dans une zone de texte. Notez que le JSON doit être valide pour que cela fonctionne. (Utilisez la console de développement pour récupérer les erreurs.) Vérifiez jsLint pour un json valide.

Le HTML:

<textarea id="myTextArea" cols=50 rows=10></textarea>
<button onclick="prettyPrint()">Pretty Print</button>

Le js:

function prettyPrint() {
    var ugly = document.getElementById('myTextArea').value;
    var obj = JSON.parse(ugly);
    var pretty = JSON.stringify(obj, undefined, 4);
    document.getElementById('myTextArea').value = pretty;
}

Commencez par essayer une saisie simple comme: {"a": "hello", "b": 123}

Une jolie impression simple de JSON peut être faite assez facilement. Essayez ce code js: ( jsFiddle ici )

// arbitrary js object:
var myJsObj = {a:'foo', 'b':'bar', c:[false,2,null, 'null']};

// using JSON.stringify pretty print capability:
var str = JSON.stringify(myJsObj, undefined, 4);

// display pretty printed object in text area:
document.getElementById('myTextArea').innerHTML = str;

Pour ce code HTML:

<textarea id="myTextArea" cols=50 rows=25></textarea>

Et consultez la documentation JSON.stringify .

88
Paul Sasik

Je ne pense pas que cela puisse être fait avec des textareas classiques. Ce que vous pouvez faire (et comment la plupart des éditeurs de code en ligne le font) est de créer une zone de texte transparente qui se superpose au-dessus d’un div contenant le code stylé. L'utilisateur serait toujours capable de taper et d'interagir avec l'entrée (et les événements de formulaire associés sont déclenchés), et vous pouvez afficher la coloration en surbrillance dans la div que l'utilisateur verra visuellement (Voir Textarea qui peut effectuer la syntaxe mettre en évidence à la volée? )

Pour ce qui est du format JSON, j’ajouterais des événements personnalisés à la zone de texte de sorte que, lorsqu'un utilisateur tape ou colle quelque chose, l'exécute via un prettificateur Javascript JSON (voir Comment puis-je imprimer en JSON avec JavaScript? ) re-peupler le div et textarea en conséquence

0
trekforever

Pour l'étape d'analyse, vous allez simplement vouloir JSON.parse le contenu de la zone de texte et gérer les erreurs dues à une mauvaise entrée.

Pour la partie mise en forme de votre question, utilisez JSON.stringify(blob, undefined, 2). Si vous avez besoin de couleurs, vous pouvez également utiliser un simple composant de format/couleur JSON écrit dans React:

const HighlightedJSON = ({ json }: Object) => {
  const highlightedJSON = jsonObj =>
    Object.keys(jsonObj).map(key => {
      const value = jsonObj[key];
      let valueType = typeof value;
      const isSimpleValue =
        ["string", "number", "boolean"].includes(valueType) || !value;
      if (isSimpleValue && valueType === "object") {
        valueType = "null";
      }
      return (
        <div key={key} className="line">
          <span className="key">{key}:</span>
          {isSimpleValue ? (
            <span className={valueType}>{`${value}`}</span>
          ) : (
            highlightedJSON(value)
          )}
        </div>
      );
    });
  return <div className="json">{highlightedJSON(json)}</div>;
};

Voyez-le fonctionner dans ce CodePen: https://codepen.io/benshope/pen/BxVpjo

J'espère que cela pourra aider!

0
benshope