<commit_before><dom-module id="grid-crud-demos">
  <template>
    <style include="vaadin-component-demo-shared-styles">
      :host {
        display: block;
      }
    </style>

    <style>
      vaadin-grid {
        text-transform: none;
      }
    </style>


    <h3>Create, Read, Update and Delete</h3>
    <p>
      Grid renderers and JavaScript functions can be used to implement inline editing.
    </p>
    <p>
      <b>Note:</b> Remember to call <code>grid.clearCache()</code> to show updated data.
    </p>
    <vaadin-demo-snippet id='grid-crud-demos-crud'>
      <template preserve-content>
        <style>
          vaadin-grid vaadin-text-field {
            width: 100%;
          }
        </style>
        <x-array-data-provider></x-array-data-provider>

        <div style="margin-bottom: 20px">
          <vaadin-text-field id="firstname" label="First Name"></vaadin-text-field>
          <vaadin-text-field id="lastname" label="Last Name"></vaadin-text-field>
          <vaadin-button id="add-btn">Add</vaadin-button>
        </div>

        <vaadin-grid theme="compact">
          <vaadin-grid-column resizable></vaadin-grid-column>
          <vaadin-grid-column resizable></vaadin-grid-column>
          <vaadin-grid-column width="12em" resizable></vaadin-grid-column>
          <vaadin-grid-column width="14em"></vaadin-grid-column>
        </vaadin-grid>
        <script>
          window.addDemoReadyListener('#grid-crud-demos-crud', function(document) {
            const grid = document.querySelector('vaadin-grid');
            const firstname = document.querySelector('#firstname');
            const lastname = document.querySelector('#lastname');

            const addBtn = document.querySelector('#add-btn');

            addBtn.addEventListener('click', function() {
              if (firstname.value && lastname.value) {
                grid.items.unshift({name: {first: firstname.value, last: lastname.value}});
                grid.clearCache();
                firstname.value = lastname.value = '';
              } else {
                alert('First Name and Last Name required');
              }
            });

            const columns = document.querySelectorAll('vaadin-grid-column');

            columns[0].headerRenderer = function(root) {
              root.textContent = 'First Name';
            };
            columns[0].renderer = function(root, column, model) {
              let textField = root.firstElementChild;
              if (!textField) {
                textField = new Vaadin.TextFieldElement();
                root.appendChild(textField);
              }
              textField.setAttribute('id', 'first-' + model.index);
              textField.value = model.item.name.first;
              textField.readonly = true;
            };

            columns[1].headerRenderer = function(root) {
              root.textContent = 'Last Name';
            };
            columns[1].renderer = function(root, column, model) {
              let textField = root.firstElementChild;
              if (!textField) {
                textField = new Vaadin.TextFieldElement();
                root.appendChild(textField);
              }
              textField.setAttribute('id', 'last-' + model.index);
              textField.value = model.item.name.last;
              textField.readonly = true;
            };

            columns[2].headerRenderer = function(root) {
              root.textContent = 'Email';
            };
            columns[2].renderer = function(root, column, model) {
              root.textContent = model.item.name.first + '.' + model.item.name.last + '@example.com';
            };

            columns[3].renderer = function(root, column, model) {
              let wrapper = root.firstElementChild;
              if (!wrapper) {
                root.innerHTML =
                  '<div style="text-align: right">' +
                    '<vaadin-button aria-label="Edit" theme="icon" focus-target>' +
                      '<iron-icon icon="lumo:edit"></iron-icon>' +
                    '</vaadin-button>' +
                    '<vaadin-button aria-label="Delete" theme="icon error" style="margin-left: 5px">' +
                      '<iron-icon icon="lumo:cross"></iron-icon>' +
                    '</vaadin-button>' +
                    '<vaadin-button aria-label="Save" theme="primary" focus-target hidden>Save</vaadin-button>' +
                    '<vaadin-button aria-label="Cancel" hidden style="margin-left: 5px">Cancel</vaadin-button>' +
                  '</div>';
                wrapper = root.firstElementChild;

                const buttons = wrapper.querySelectorAll('vaadin-button')
                buttons[0].addEventListener('click', function() {
                  grid.querySelector('#first-' + wrapper._model.index).focus();
                  updateTextFieldsVisibility(wrapper._model.index, true);
                  updateButtonsVisibility(wrapper, true);
                });
                buttons[1].addEventListener('click', function(event) {
                  var index = grid.items.indexOf(wrapper._model.item);
                  grid.items.splice(index, 1);
                  grid.clearCache();
                });
                buttons[2].addEventListener('click', function() {
                  model.item.name.first = grid.querySelector('#first-' + wrapper._model.index).value;
                  model.item.name.last = grid.querySelector('#last-' + wrapper._model.index).value;

                  updateTextFieldsVisibility(wrapper._model.index, false);
                  updateButtonsVisibility(wrapper, false);
                  grid.clearCache();
                  buttons[0].focus();
                });
                buttons[3].addEventListener('click', function(event) {
                  updateTextFieldsVisibility(wrapper._model.index, false);
                  updateButtonsVisibility(wrapper, false);
                  grid.clearCache();
                  buttons[0].focus();
                });
              }

              wrapper._model = model;
              console.log(model, root, root._model);
            };

            function updateTextFieldsVisibility(index, editing) {
              if (editing) {
                grid.querySelector('#first-' + index).removeAttribute('readonly');
                grid.querySelector('#last-' + index).removeAttribute('readonly');
              } else {
                grid.querySelector('#first-' + index).setAttribute('readonly', true);
                grid.querySelector('#last-' + index).setAttribute('readonly', true);
              }
            }

            function updateButtonsVisibility(wrapper, editing) {
              if (editing) {
                wrapper.querySelectorAll('[theme~="icon"]').forEach(function(btn) {
                  btn.setAttribute('hidden', true);
                });
                wrapper.querySelectorAll('vaadin-button:not([theme~="icon"])').forEach(function(btn) {
                  btn.removeAttribute('hidden');
                });
              } else {
                wrapper.querySelectorAll('[theme~="icon"]').forEach(function(btn) {
                  btn.removeAttribute('hidden');
                });
                wrapper.querySelectorAll('vaadin-button:not([theme~="icon"])').forEach(function(btn) {
                  btn.setAttribute('hidden', true);
                });
              }
            }
<commit_msg>Simplify code in CRUD demo<commit_after><dom-module id="grid-crud-demos">
  <template>
    <style include="vaadin-component-demo-shared-styles">
      :host {
        display: block;
      }
    </style>

    <style>
      vaadin-grid {
        text-transform: none;
      }
    </style>


    <h3>Create, Read, Update and Delete</h3>
    <p>
      Grid renderers and JavaScript functions can be used to implement inline editing.
    </p>
    <p>
      <b>Note:</b> Remember to call <code>grid.clearCache()</code> to show updated data.
    </p>
    <vaadin-demo-snippet id='grid-crud-demos-crud'>
      <template preserve-content>
        <style>
          vaadin-grid vaadin-text-field {
            width: 100%;
          }

          vaadin-grid vaadin-button {
            margin-left: 5px;
          }
        </style>
        <x-array-data-provider></x-array-data-provider>

        <div style="margin-bottom: 20px">
          <vaadin-text-field id="firstname" label="First Name"></vaadin-text-field>
          <vaadin-text-field id="lastname" label="Last Name"></vaadin-text-field>
          <vaadin-button id="add-btn">Add</vaadin-button>
        </div>

        <vaadin-grid theme="compact">
          <vaadin-grid-column resizable></vaadin-grid-column>
          <vaadin-grid-column resizable></vaadin-grid-column>
          <vaadin-grid-column width="12em" resizable></vaadin-grid-column>
          <vaadin-grid-column width="14em"></vaadin-grid-column>
        </vaadin-grid>
        <script>
          window.addDemoReadyListener('#grid-crud-demos-crud', function(document) {
            const grid = document.querySelector('vaadin-grid');
            const firstname = document.querySelector('#firstname');
            const lastname = document.querySelector('#lastname');

            const addBtn = document.querySelector('#add-btn');

            addBtn.addEventListener('click', function() {
              if (firstname.value && lastname.value) {
                grid.items.unshift({name: {first: firstname.value, last: lastname.value}});
                grid.clearCache();
                firstname.value = lastname.value = '';
              } else {
                alert('First Name and Last Name required');
              }
            });

            const columns = document.querySelectorAll('vaadin-grid-column');

            columns[0].headerRenderer = function(root) {
              root.textContent = 'First Name';
            };
            columns[0].renderer = function(root, column, model) {
              let textField = root.firstElementChild;
              if (!textField) {
                textField = new Vaadin.TextFieldElement();
                root.appendChild(textField);
              }
              textField.value = model.item.name.first;
              textField.setAttribute('focus-target', true);
              textField.readonly = true;
            };

            columns[1].headerRenderer = function(root) {
              root.textContent = 'Last Name';
            };
            columns[1].renderer = function(root, column, model) {
              let textField = root.firstElementChild;
              if (!textField) {
                textField = new Vaadin.TextFieldElement();
                root.appendChild(textField);
              }
              textField.value = model.item.name.last;
              textField.setAttribute('focus-target', true);
              textField.readonly = true;
            };

            columns[2].headerRenderer = function(root) {
              root.textContent = 'Email';
            };
            columns[2].renderer = function(root, column, model) {
              root.textContent = model.item.name.first + '.' + model.item.name.last + '@example.com';
            };

            columns[3].renderer = function(root, column, model) {
              let wrapper = root.firstElementChild;
              if (!wrapper) {
                root.innerHTML =
                  '<div style="text-align: right">' +
                    '<vaadin-button aria-label="Edit" theme="icon" focus-target>' +
                      '<iron-icon icon="lumo:edit"></iron-icon>' +
                    '</vaadin-button>' +
                    '<vaadin-button aria-label="Delete" theme="icon error">' +
                      '<iron-icon icon="lumo:cross"></iron-icon>' +
                    '</vaadin-button>' +
                    '<vaadin-button aria-label="Save" theme="primary" focus-target hidden>Save</vaadin-button>' +
                    '<vaadin-button aria-label="Cancel" hidden>Cancel</vaadin-button>' +
                  '</div>';
                wrapper = root.firstElementChild;

                const buttons = wrapper.querySelectorAll('vaadin-button');
                // EDIT
                buttons[0].addEventListener('click', function() {
                  updateTextFieldsVisibility(wrapper.idx, true);
                  updateButtonsVisibility(buttons, wrapper.idx, true);
                  getTextField(columns[0], wrapper.idx).focus();
                });
                // DELETE
                buttons[1].addEventListener('click', function(event) {
                  grid.items.splice(wrapper.idx, 1);
                  grid.clearCache();
                });
                // SAVE
                buttons[2].addEventListener('click', function() {
                  grid.items[wrapper.idx].name.first = getTextField(columns[0], wrapper.idx).value;
                  grid.items[wrapper.idx].name.last = getTextField(columns[1], wrapper.idx).value;
                  buttons[3].click();
                });
                // CANCEL
                buttons[3].addEventListener('click', function(event) {
                  updateTextFieldsVisibility(wrapper.idx, false);
                  updateButtonsVisibility(buttons, wrapper.idx, false);
                  grid.clearCache();
                  buttons[0].focus();
                });
              }

              // We reuse rendered content, but maintain a property with the index for actions
              wrapper.idx = model.index;
            };

            // Returns the vaadin-text-element for a given column and row
            function getTextField(column, index) {
              const cell = column._allCells.filter(cell => cell._model && cell._model.index === index)[0];
              return cell._content.firstElementChild;
            }

            function updateTextFieldsVisibility(index, editing) {
              getTextField(columns[0], index).readonly = !editing;
              getTextField(columns[1], index).readonly = !editing;
            }

            function updateButtonsVisibility(buttons, index, editing) {
              buttons[0].hidden = buttons[1].hidden = editing;
              buttons[2].hidden = buttons[3].hidden = !editing;
            }

{'fraction_non_alphanumeric': 0.13228809407153355, 'fraction_numerical': 0.004409603135717786, 'mean_word_length': 1.716866324396273, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 114, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3187484', 'n_tokens_mistral': 3784, 'n_tokens_neox': 3589, 'n_words': 619}