Closed bgarrant closed 6 years ago
@bgarrant You can use nested array inputs to save data in the same format as what your grid fieldtype will allow.
Here's a CodePen that shows how I recreated one of my grid fieldsets using Workshop. The resultant YAML looks like this:
crew:
1:
name: John Doe
role: Director
responsibilities: Make the show awesome.
2:
name: Jane Crow
role: Choreographer
responsibilities: Teach people to dance.
The trick is making sure each row's key is unique.
Also, if this is a form to edit content, you can use Statamic's {{ zero_index }}
to pre-assign any pre-existing keys, a la <input name="crew[{{ zero_index }}][name]"/>
and then assign your starting key in the template directly, a la:
{{ some_grid }}
<div class="flex">
<b class="add">Add</b>
<input name="crew[{{ zero_index }}][name]" value="{{ name }}">
<input name="crew[{{ zero_index }}][role]" value="{{ role }}">
<input name="crew[{{ zero_index }}][responsibilities]" value="{{ responsibilities }}">
<b class="remove">Remove</b>
</div>
{{ if last }}
<script>var key = {{ index }}</script>
{{ /if }}
{{ /some_grid }}
edit: if editing content, you'll also have to assign event listeners to any add/remove buttons that pre-exist.
@danielfowler this is great. Do you know how to toggle the add and remove row for the ADD and EDIT forms? I am horrible at JS. Thanks
I don't follow what you mean. If you're trying to hide the add/remove buttons, you can use CSS.
I am laying out the data in a table. In my ADD form I need a way to add table rows and remove them. I tried this method but there must be a better way https://smarttutorials.net/add-remove-table-rows-jquery/. You can see more details in this thread https://statamic.slack.com/archives/C04CM7HA9/p1532796713000064 if you use Slack
Does your method handle the ADD and DELETE if rows? I do not have to use a table at all.
No, you don't have to use a table. A table for layout is never advised. My method does handle adding and deleting rows, without jQuery. I hate depending on libraries. Vanilla JS ftw.
@danielfowler so all I need is your code and it will add and remove rows? What else do I need on the edit form? Just the ID of the entry and it will render the existing grid and allow add and remove also?
I asked this in Slack also, but how can I add an Edit event listener to this @danielfowler ? That is all I need to complete this I think. Thanks
Easy! I think... Try <b class="add" onclick="addEmptyRow(this.parentNode)">Add</b>
and <b class="remove" onclick="removeRow(this.parentNode)">Remove</b>
in your {{ workshop:entry:edit }}
HTML template
The remove works but ADD is not. Typo maybe @danielfowler ?
{{ event_schedule }}
<div class="flex">
<b class="add" onclick="addEmptyRow(this.parentNode)">Add</b>
<input name="event_schedule[{{ zero_index }}][schedule_day]" value="{{ schedule_day }}">
<input name="event_schedule[{{ zero_index }}][schedule_time]" value="{{ schedule_time }}">
<input name="event_schedule[{{ zero_index }}][schedule_details]" value="{{ schedule_details }}">
<b class="remove" onclick="removeRow(this.parentNode)">Remove</b>
</div>
{{ if last }}
<script>var key = {{ index }}</script>
{{ /if }}
{{ /event_schedule }}
I may have it now. I will post back if any issues. Thanks so much!
I forked my original CodePen to show it working with pre-existing content.
@danielfowler The add part only is working as this <b class="add" onclick="addEmptyRow()">Add Day</b>
{{ event_schedule }}
<div class="flex">
<b class="add" onclick="addEmptyRow()">Add Day</b>
<input name="event_schedule[{{ zero_index }}][schedule_day]" value="{{ schedule_day }}">
<input name="event_schedule[{{ zero_index }}][schedule_time]" value="{{ schedule_time }}">
<input name="event_schedule[{{ zero_index }}][schedule_details]" value="{{ schedule_details }}">
<b class="remove" onclick="removeRow(this.parentNode)">Remove</b>
</div>
{{ if last }}
<script>var key = {{ index }}</script>
{{ /if }}
{{ /event_schedule }}
Your addEmptyRow()
needs to be addEmptyRow(this.parentNode)
@danielfowler with that it fails to add row. here is what I have. Thank agin for helping. I am close
<script>
var container = document.querySelector('#container')
var key = 0
function addEmptyRow(el) {
key++ // increment the key so it's always unique
// recreate a new grid row using HTML
var blankHTML =
'<b class="add">Add</b>' +
'<input name="event_schedule[' + key + '][schedule_day]" placeholder="Day">' +
'<input name="event_schedule[' + key + '][schedule_time]" placeholder="Time">' +
'<input name="event_schedule[' + key + '][schedule_details]" placeholder="Details">' +
'<b class="remove">Remove</b>';
var newNode = document.createElement('div') // create DOM node for row
newNode.classList.add('flex') // arbitrary class names
newNode.innerHTML = blankHTML // fill the row with its HTML
// add/remove buttons allow user to add and remove rows
// a more advanced JS programmer might enable drag & drop
var addButton = newNode.querySelector('.add')
var removeButton = newNode.querySelector('.remove')
// add event listeners to the new add/remove buttons
addButton.onclick = function(e) {addEmptyRow(newNode)}
removeButton.onclick = function(e) {removeRow(newNode)}
var insertedNode = container.insertBefore(newNode,el)
}
function removeRow(el) {
el.parentNode.removeChild(el)
}
window.addEventListener('load',function(e) {
container.innerHTML = '' // clean out the container by default
})
</script>
<div id="container"></div>
{{ event_schedule }}
<div class="flex">
<b class="add" onclick="addEmptyRow(this.parentNode)">Add Day</b>
<input name="event_schedule[{{ zero_index }}][schedule_day]" value="{{ schedule_day }}">
<input name="event_schedule[{{ zero_index }}][schedule_time]" value="{{ schedule_time }}">
<input name="event_schedule[{{ zero_index }}][schedule_details]" value="{{ schedule_details }}">
<b class="remove" onclick="removeRow(this.parentNode)">Remove</b>
</div>
{{ if last }}
<script>var key = {{ index }}</script>
{{ /if }}
{{ /event_schedule }}
</div
Remove works perfect. Add is not making a row
Put your {{ events_schedule }}
tag pair inside the <div id="container"></div>
I've updated my CodePen since I first posted it. See it here: https://codepen.io/danielfowler/pen/GBOyjG
Thanks so much @danielfowler . Think I got it now. :)
Is your feature request related to a problem? Please describe. I have a site that we need to allow a client to add data to a grid from a frontend Workshop form. Looks like people have been able to do this before https://statamic.com/forum/1850-grid-data-not-saving-from-front-end-prof, https://statamic.com/forum/1357-edit-grid-fields-or-table-field-on-the-f.
Describe the solution you'd like We need to know how to add a grid fieldtype to a Workshop frontend form. There must be a way this can be done already. Something like you see in the backend where you can just add rows.
https://cl.ly/320t0L3h0U0Z
Describe alternatives you've considered I am not great at JS but I am sure there must be a way to do this.
Additional context