how to change value of v-if condition of current item in loop (on click) - vue.js

In my Vue.js app, I have a list of contacts in a v-for loop, each with a corresponding 'edit' button; I want to toggle the v-if="="!isEditingContact" condition for only the selected contact. I have the index of the button/contact to be edited, but I don't know how to toggle the 'isEditingContact' condition for the selected contact.
My component:
<template>
<div class="container" id="project-edit">
<section class="client-data">
<!-- show static if editMode FALSE -->
<dl v-if="!isEditingClient">
<!-- SNIP-->
</dl>
<!-- show FORM if editMode TRUE -->
<fieldset v-if="isEditingClient">
<!-- SNIP -->
</fieldset>
<div class="buttons">
<button v-if=!isEditingClient id="edit-client" v-on:click="editMode">edit</button>
<button v-if=isEditingClient v-on:click="cancelEdit">cancel</button>
<button v-if=isEditingClient v-on:click="post">save changes</button>
</div>
</section><!-- END .client-data -->
<section class="gig-data">
<!-- show static if editMode FALSE -->
<dl v-if="!isEditingGig">
<!-- SNIP-->
</dl>
<!-- show FORM if editMode TRUE -->
<fieldset v-if="isEditingGig">
<!-- SNIP-->
</fieldset>
<div class="buttons">
<button v-if=!isEditingGig id="edit-gig" v-on:click="editMode">edit</button>
<button v-if=isEditingGig v-on:click="cancelEdit">cancel</button>
<button v-if=isEditingGig v-on:click="post">save changes</button>
</div>
</section><!-- END .gig-data -->
<section class="contacts-wrapper">
<!-- show static if editMode FALSE -->
<dl>
<dt>contacts:</dt>
<dd>
<ul class="contacts">
<li v-if="!isEditingContact" v-for="(contact, ix) in project.contacts" v-bind:key="??">
{{ contact.name }}<br />
{{ contact.title }}<br />
{{ contact.email }}<br />
{{ contact.phone }}
<div class="buttons">
<button v-if=!isEditingContact id="edit-contact" v-on:click="editContact(contact, ix)">edit</button>
<button v-if=isEditingContact v-on:click="cancelEdit">cancel</button>
<button v-if=isEditingContact v-on:click="post">save changes</button>
</div>
</li>
</ul>
<!-- show FORM if editMode TRUE -->
<fieldset v-if="isEditingContact">
<!--
SNIP:
FORM TO BE DISPLAYED IN PLACE OF THE SELECTED CONTACT,
AND W/OUT HIDING OTHER CONTACTS
-->
</fieldset>
</dd>
</dl>
</section>
</div>
</template>
<script>
export default {
props: [ "projectID" ],
components: {
},
data () {
return {
id: this.$route.params.id,
title: "Edit Project",
subtitle: "ID: " + this.$route.params.id,
project: {},
contactInfo: {},
workLocation: true,
submitted: false,
isEditingClient: false,
isEditingGig: false,
isEditingContact: false
}
}, // data
created: function() {
this.$http.get("https://xyz.dataworld.com/projects/" + this.id + ".json")
.then(function(data) {
return data.json();
}).then(function(data) {
this.project = data;
})
}, // created
methods: {
addContactInfo: function(e) {
e.preventDefault();
this.projectID = this.id;
this.project.contacts.push(this.contactInfo);
this.contactInfo = {};
},
editMode: function(e) {
const buttonID = e.currentTarget.id;
switch (buttonID) {
case "edit-client":
this.isEditingClient = !this.isEditingClient;
break;
case "edit-gig":
this.isEditingGig = !this.isEditingGig;
break;
// case "edit-contact": ... this is uselesss, since it would hide all contacts as it shows the form
// this.isEditingContact = !this.isEditingContact;
// break;
default:
}
},
editContact: function(e) {
},
cancelEdit: function() {
this.isEditingClient = false;
this.isEditingGig = false;
this.isEditingContacts = false;
},
post: function() {
console.log(this.project);
this.$http.post("https://sr-giglog.firebaseio.com/projects.json", this.project)
.then(function(data){
this.submitted = true;
}
)} // post function
} // methods
}
</script>

Most commonly this is done by adding a flag to the individual objects in your list. In this case, an editing flag, or whatever you want to call it. You would initialize it with false. You can add this flag either server side or client side. If you want to do it client side it would look something like this:
this.$http.get("https://xyz.dataworld.com/projects/" + this.id + ".json")
.then(data => data.json())
.then(data => {
// add the editing property
for (let contact of data.contacts)
this.$set(contact, 'editing', false)
this.project = data
})
Then, use that property in your template.
<section class="contacts-wrapper">
<!-- show static if editMode FALSE -->
<dl>
<dt>contacts:</dt>
<dd>
<ul class="contacts">
<li v-if="!contact.editing" v-for="(contact, ix) in project.contacts" v-bind:key="??">
{{ contact.name }}<br />
{{ contact.title }}<br />
{{ contact.email }}<br />
{{ contact.phone }}
<div class="buttons">
<button v-if="!contact.editing" id="edit-contact" v-on:click="contact.editing = true">edit</button>
<button v-if="contact.editing" v-on:click="contact.editing = false">cancel</button>
<button v-if="contact.editing" v-on:click="post">save changes</button>
</div>
</li>
</ul>
<!-- show FORM if editMode TRUE -->
<fieldset v-if="contact.edting">
...
</fieldset>
</dd>
</dl>
</section>

You can store editing contact's id and check that inside v-if.
If you stored the id of contact that is being edited in editingContactId then you can modify your code to this:
<ul class="contacts">
<li v-for="(contact, ix) in project.contacts" v-bind:key="??">
{{ contact.name }}<br />
{{ contact.title }}<br />
{{ contact.email }}<br />
{{ contact.phone }}
<div class="buttons">
<button v-if="editingContactId!=contact.id" id="edit-contact" v-on:click="editContact(contact, ix)">edit</button>
<button v-if="editingContactId==contact.id" v-on:click="cancelEdit">cancel</button>
<button v-if="editingContactId==contact.id" v-on:click="post">save changes</button>
</div>
</li>
</ul>

If it helps anyone, here's my revised, working solution (at least this reflects specifically what I was asking to achieve in my OP):
My component:
<template>
<div class="container" id="project-edit">
<section class="client-data">
<!-- show static if editMode FALSE -->
<dl v-if="!isEditingClient">
<!-- SNIP-->
</dl>
<!-- show FORM if editMode TRUE -->
<fieldset v-if="isEditingClient">
<!-- SNIP -->
</fieldset>
<div class="buttons">
<button v-if=!isEditingClient id="edit-client" v-on:click="editMode">edit</button>
<button v-if=isEditingClient v-on:click="cancelEdit">cancel</button>
<button v-if=isEditingClient v-on:click="post">save changes</button>
</div>
</section><!-- END .client-data -->
<section class="gig-data">
<!-- show static if editMode FALSE -->
<dl v-if="!isEditingGig">
<!-- SNIP-->
</dl>
<!-- show FORM if editMode TRUE -->
<fieldset v-if="isEditingGig">
<!-- SNIP-->
</fieldset>
<div class="buttons">
<button v-if=!isEditingGig id="edit-gig" v-on:click="editMode">edit</button>
<button v-if=isEditingGig v-on:click="cancelEdit">cancel</button>
<button v-if=isEditingGig v-on:click="post">save changes</button>
</div>
</section><!-- END .gig-data -->
<section class="contacts-wrapper">
<!-- show static if editMode FALSE -->
<dl>
<dt>contacts:</dt>
<dd>
<li v-for="(contact, ix) in project.contacts">
<!-- show orig data if editMode FALSE -->
<div v-if="!contact.editingContact">
{{ contact.name }} ({{ ix }})<br />
{{ contact.title }}<br />
{{ contact.email }}<br />
{{ contact.phone }}
<div class="buttons">
<button v-if=!contact.editingContact id="edit-contact" v-on:click="contact.editingContact = true">edit</button>
</div>
</div>
<!-- show FORM if editMode TRUE -->
<fieldset v-if="contact.editingContact">
<!-- SNIP: FORM ... -->
<div class="buttons">
<!-- I realize that the v-if attributes are not necessary here -->
<button v-if=contact.editingContact v-on:click="contact.editingContact = false">cancel</button>
<button v-if=contact.editingContact v-on:click="post">save changes</button>
</div>
</fieldset>
</li>
</dd>
</dl>
</section>
</div>
</template>
<script>
export default {
props: [ "projectID" ],
components: {
},
data () {
return {
id: this.$route.params.id,
title: "Edit Project",
subtitle: "ID: " + this.$route.params.id,
project: {},
contactInfo: {},
workLocation: true,
submitted: false,
isEditingClient: false,
isEditingGig: false,
}
}, // data
created: function() {
this.$http.get("https://xyz.dataworld.com/projects/" + this.id + ".json")
.then(data => data.json())
.then(data => {
for (let contact of data.contacts) {
this.$set(contact, 'editingContact', false)
}
this.project = data;
})
}, // created
methods: {
addContactInfo: function(e) {
e.preventDefault();
this.projectID = this.id;
this.project.contacts.push(this.contactInfo);
this.contactInfo = {};
},
editMode: function(e) {
const buttonID = e.currentTarget.id;
switch (buttonID) {
case "edit-client":
this.isEditingClient = !this.isEditingClient;
break;
case "edit-gig":
this.isEditingGig = !this.isEditingGig;
break;
default:
}
},
editContact: function(e) {
},
cancelEdit: function() {
this.isEditingClient = false;
this.isEditingGig = false;
},
post: function() {
console.log(this.project);
this.$http.post("https://sr-giglog.firebaseio.com/projects.json", this.project)
.then(function(data){
this.submitted = true;
}
)} // post function
} // methods
}
</script>
Now, if you'd all just stand by while I prepare my next twelve questions ...

Related

Vue v-model/v-for doesn't update on mount, but after first manual change

I have a dropdown list "functions" that is filled with database entries and a dropdown list with 2 hardcoded entries. When the vue website is opened the dropdown list remains empty but as soon as I change the value of the other dropdown field the desired data from the database is available.
I'm a bit confused because I expected that adding "retrieveFunctions()" into the mounted() function would trigger the v-for, and even more confused that changing something in another select field suddenly triggers it.
The HTML code:
<template>
<div class="submit-form">
<div v-if="!submitted">
<div class="row">
<div class="col-sm-12">
<p><a style="width:500px" class="btn btn-info" data-toggle="collapse" href="#generalInformation" role="button" aria-expanded="true" >
General Information</a></p>
<div class="collaps show" id="generalInformation">
<!-- NAME -->
<div class="form-group">
<input placeholder="Name" type="text" class="form-control"
id="name" required v-model="component.name" name="name">
</div>
<!-- DOMAIN -->
<div class="input-group mb-3">
<div class="input-group-prepend">
<label style="width:100px" class="input-group-text" for="inputGroupDomain">Domain</label>
</div>
<select v-model="component.domain"
class="custom-select"
id="inputGroupDomain"
>
<option value="Power System">Power System</option>
<option value="ICT">ICT</option>
</select>
</div>
<!-- FUNCTION -->
<div class="input-group mb-3">
<div class="input-group-prepend">
<label style="width:100px" class="input-group-text" for="inputGroupFunction">Functions</label>
</div>
<select v-model="_function" class="custom-select" id="inputGroupFunction">
<option :class="{ active: index == currentIndex }"
v-for="(_function, index) in functions"
:key="index"
value= _function.name>
{{ _function.name }}
</option>
</select>
</div>
</div>
<p>
<button #click="saveComponent" class="btn btn-success">Add Component</button>
</p>
</div>
</div>
</div>
<div v-else>
<h4>Component was added succesfully!</h4>
<button class="btn btn-success" #click="newComponent">Proceed</button>
</div>
The script part:
<script>
import FunctionDataService from "../services/FunctionDataService";
export default {
name: "add-component",
data() {
return {
component: {
id: null,
name: "",
type: "",
domain: "",
},
submitted: false
};
},
methods: {
retrieveFunctions() {
FunctionDataService.getAll()
.then(response => {
this.functions = response.data;
console.log(response.data);
})
.catch(e => {
console.log(e);
});
},
refreshList() {
this.retrieveFunctions();
},
},
mounted() {
this.retrieveFunctions();
}
};
</script>
refreshList() {
this.retrieveFunctions();
},
},
mounted() {
this.retrieveFunctions();
}
};
</script>
State in the beginning: Dropdown list empty
State after selecting something in the upper dropdown list: Database entries are visible and correct
You need to initiate all responsive properties on the data return object with either a value (empty string, array, object, etc) or null. Currently it's missing the _function attribute used in the select v-model and the functions array used in the v-for. You can try to change the data to the following:
data() {
return {
_function: "",
functions: [],
component: {
id: null,
name: "",
type: "",
domain: "",
},
submitted: false
};
},

nesting an object inside an object

Looking for some tips on how to nest objects inside objects using a form. My form currently changes the key and value of an object. However, I'm now wanting a second button to be able to create a child (correct termanology?)form input. below you can see an example. I've spent the morning looking at props but I'm unsure if this is the correct way to go, any suggestions are greatly appriciated
{
"color": "black",
"category": "hue",
"type": "primary",
"code": {
"rgba": [255,255,255,1],
"hex": "#000"
}
},
<form id="app">
<h1>
Title goes here
</h1>
<hr>
<div class="row">
<div class="col-xs-2">
<button type="button" v-on:click="addNewObject" class="btn btn-block btn-success">
(Add +) Parent
</button>
</div>
<div class="col-xs-10 text_info">
Click 'Add +' to add an object
</div>
</div>
<div v-for="(object, index) in objects">
<div class="row">
<div class="col-xs-1">
<label> </label>
<button type="button" v-on:click="removeObject(index)" class="btn btn-rem btn-block btn-danger">
Delete
</button>
<button type="button" v-on:click="addNewChildObject()" class="btn btn-rem btn-block btn-success btn-suc">
add { }
</button>
</div>
<div class="form-group col-xs-7">
<div class="test">
<select v-model="object.type" class="selectBox classic">
<option value="" disabled selected hidden>Choose Datatype</option>
<option v-for="type in types"> {{ type }}</option>
</select>
<input v-model="object.name" :name="'objects[' + index + '][name]'" type="string" class="form-control" placeholder="Enter key">
<input v-model="object.dataValue" :name="'objects[' + index + '][dataValue]'" type="string" class="form-control" placeholder="Enter value">
</div>
</div>
</div>
</div>
<hr>
<div>
<pre v-if="seen">{{ mappedObjects }}</pre>
</div>
<button type="button" class="btn-primary" v-on:click="seen = !seen">{{ seen ? 'Click to Hide the JSON' : 'Click to Show the JSON' }}</button>
</form>
const getDefaultObject = () => ({
name: '',
dataValue: '',
type: ''
})
const app = new Vue({
el: '#app',
computed: {
mappedObjects() {
return this.objects.map(({
name,
dataValue,
type
}) => ({
[name]: dataValue,
type
}))
}
},
props: {
},
data() {
return {
seen: false,
types: ['string', 'character', 'number', 'int', 'floating-point', 'boolean', 'date;'],
objects: []
}
},
methods: {
addNewObject: function() {
this.objects.push(getDefaultObject())
},
removeObject: function(index) {
Vue.delete(this.objects, index);
},
addNewChildObject: function () {
}
}
})
If you want n forms with n children just create a model for it following that same structure and pass props to the form.
parent = {
...props,
children: []
}
child = {
...props
}
If the forms are too complex (or a little complex really), split them in separate components and pass children as props.
If you want to use the same form both in parent and children take a look at slots, they will allow you to create flexible layouts.

Vue-formulate - Group item collapsible / toggle collapse

Is there a possibility to make group item collapsible?
<FormulateInput type="group" name="employments" :repeatable="true" label="Employments"
add-label="+ Add Employment" #default="groupProps">
<!-- Clickable area -->
<div class="group text-sm font-semibold py-2 cursor-pointer relative" #click="groupProps.showForm">
....
</div>
<!-- Nested form: must be collapsible accordion -->
<div class="nested-form" v-show="groupProps.showForm">
....
</div>
</FormulateInput>
I thought to add showForm property to the group context.
For this I need to do Custom input types or is there some other way?
If anyone has any other ideas?
Thanks
I figured it out with the gist of #jpschroeder.
CollapsableGroupItem.vue:
<template>
<div class="group-item" :data-is-open="itemId === showIndex">
<div class="group group-item-title text-sm font-semibold py-2 cursor-pointer relative hover:text-blue-400" #click="toggleBody">
<slot name="title" v-bind="groupItem">#{{ context.index }}</slot>
</div>
<div class="group-item-body" v-show="itemId === showIndex">
<slot name="body">
<FormulateInput type="pelleditor" name="description" label="Description"/>
</slot>
</div>
</div>
</template>
<script>
export default {
name: "CollapsableGroupItem",
props: {
context: {
type: Object,
required: true,
},
showIndex: {
type: [Number, String],
required: true,
},
groupItem: {
type: Object,
required: true,
},
},
data () {
return {
itemId: this.context.name + this.context.index
}
},
created: function () {
// show current item
this.$emit("open", this.itemId);
},
methods: {
toggleBody() {
if (this.itemId === this.showIndex) {
// dont show anything
this.$emit("open", -1);
} else {
// show this one
this.$emit("open", this.itemId);
}
},
}
};
FormTemplate.vue:
<CollapsableGroupItem
:context="context"
:show-index="showIndex"
:group-item="educations[context.index]"
#open="showIndex = $event"
>
<template v-slot:title="education">
<span v-if="education.institution || education.degree"
>
{{ education.institution }}
<span v-if="education.institution && education.degree">at</span>
{{ education.degree }}
</span>
...
</template>
<template v-slot:body>
...
</template>
</CollapsableGroupItem>
Maybe it will help someone else or will be useful 😀

Bind class item in the loop

i want to bind my button only on the element that i added to the cart, it's working well when i'm not in a loop but in a loop anything happen. i'm not sure if it was the right way to add the index like that in order to bind only the item clicked, if i don't put the index every button on the loop are binded and that's not what i want in my case.
:loading="isLoading[index]"
here the vue :
<div class="container column is-9">
<div class="section">
<div class="columns is-multiline">
<div class="column is-3" v-for="(product, index) in computedProducts">
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src="" alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="content">
<div class="media-content">
<p class="title is-4">{{product.name}}</p>
<p class="subtitle is-6">Description</p>
<p>{{product.price}}</p>
</div>
</div>
<div class="content">
<b-button class="is-primary" #click="addToCart(product)" :loading="isLoading[index]"><i class="fas fa-shopping-cart"></i> Ajouter au panier</b-button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
here the data :
data () {
return {
products : [],
isLoading: false,
}
},
here my add to cart method where i change the state of isLoading :
addToCart(product) {
this.isLoading = true
axios.post('cart/add-to-cart/', {
data: product,
}).then(r => {
this.isLoading = false
}).catch(e => {
this.isLoading = false
});
}
You can change your isLoading to an array of booleans, and your addToCart method to also have an index argument.
Data:
return {
// ...
isLoading: []
}
Methods:
addToCart(product, index) {
// ...
}
And on your button, also include index:
#click="addToCart(product, index)"
By changing isLoading to an empty array, I don't think isLoading[index] = true will be reactive since index on isLoading doesn't exist yet. So you would use Vue.set in your addToCart(product, index) such as:
this.$set(this.isLoading, index, true)
This will ensure that changes being made to isLoading will be reactive.
Hope this works for you.
add on data productsLoading: []
on add to cart click, add loop index to productsLoading.
this.productsLoading.push(index)
after http request done, remove index from productsLoading.
this.productsLoading.splice(this.productoading.indexOf(index), 1)
and check button with :loading=productsLoading.includes(index)
You can create another component only for product card,
for better option as show below
Kindly follow this steps.
place the content of card in another vue component as shown below.
<!-- Product.vue -->
<template>
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src="" alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="content">
<div class="media-content">
<p class="title is-4">{{product.name}}</p>
<p class="subtitle is-6">Description</p>
<p>{{product.price}}</p>
</div>
</div>
<div class="content">
<b-button class="is-primary" #click="addToCart(product)" :loading="isLoading"><i class="fas fa-shopping-cart"></i> Ajouter au panier</b-button>
</div>
</div>
</div>
</templete>
<script>
export default {
name: "Product",
data() {
return {
isLoading: false
}
},
props: {
product: {
type: Object,
required: true
}
},
methods: {
addToCart(product) {
this.isLoading = true
axios.post('cart/add-to-cart/', {
data: product,
}).then(r => {
this.isLoading = false
}).catch(e => {
this.isLoading = false
});
}
}
}
</script>
Change your component content as shown below.
<template>
<div class="container column is-9">
<div class="section">
<div class="columns is-multiline">
<div class="column is-3" v-for="(product, index) in computedProducts">
<product :product="product" />
</div>
</div>
</div>
</div>
</templete>
<script>
import Product from 'path to above component'
export default {
components: {
Product
}
}
</script>
so in the above method you can reuse the component in other components as well.
Happy coding :-)

Selenuim/Protractor can't find or click in textbox

I have a code from a website as follows and I want to use the 5th line from code segment below <input type="text" placeholder="Enter Workflow Name"
Code
<div class="workflow-container ng-scope" data-ng-controller="sourceCode.Designer.uiComponents.conciergeScreen.templates.NewWorkflowController">
<div class="input">
<div class="wrapper top" data-ng-class="{'fill': hosted === true}">
<label class="welcome">What should your workflow be called?</label>
<input type="text" placeholder="Enter Workflow Name" class="workflow-name-textbox ng-valid ng-not-empty ng-touched ng-dirty ng-valid-parse" data-ng-class="{'error': errors.error}" autofocus="" data-ng-focus="select($event)" data-ng-model="conciergetitle" data-ng-model-options="{ updateOn: 'default blur', debounce: { default: 300, blur: 300 } }" data-ng-change="inputchange(designeritems)" data-ng-keyup="$event.keyCode == 13 && createnewstudioitem(designerItems[0], conciergetitle, $event)" style="">
<div class="errogory">
<div class="summary">
<!-- ngIf: errors.error || errors.category -->
</div>
<div class="category" data-ng-click="categorypicker($event)">
<label>Folder</label>
<i class="icon icon-set-assetbrowser icon-size16 ic-categoryserver"></i>
Workflow
</div>
</div>
<div class="concierge-button-grid">
<div class="concierge-button-container">
<button id="createWorkflow" data-button-error="false" class="concierge-button button-command" data-ng-disabled="!newWorkflowReady" data-ng-class="{ 'error': errors.button, 'is-disabled error' : errors.button }" data-ng-click="createnewstudioitem(designerItems[0], conciergetitle, $event)" disabled="disabled">
<!-- ngIf: !errors.button --><span data-ng-bind="getString('new_workflow_create_button')" data-ng-if="!errors.button" class="ng-binding ng-scope">Create</span><!-- end ngIf: !errors.button -->
<!-- ngIf: errors.button -->
</button>
</div>
<div class="concierge-button-container">
<button id="discardWorkflow" class="concierge-button concierge-button-discard button-command tertiary" data-ng-click="discard()">
<span data-ng-bind="getString('discard_workflow_button')" class="ng-binding">Discard</span>
</button>
</div>
</div>
</div>
<!-- ngIf: showrecent -->
<!-- ngIf: showrecent -->
</div>
I want to click in the textbox so that I can clear the text. I have tried the following:
describe("New Screen", function () {
it("Should give textbox a new name", function () {
browser.sleep(10000);
console.log('Enter new name');
var editName = element.all(by.className('.workflow-name-textbox'));
editName.first().click().then(function () {
console.log('Clicked on Create');
})
browser.sleep(10000);
})
I get a error: Index out of bound. Trying to access element at index: 0 ...
if I change my code above to:
var editName = element.all(by.css('.workflow-name-textbox'));
editName.click().then(function () {
console.log('Clicked on Create');
I dont get errors but I dont see any clicking going on.
I know my protractor works because I have navigated to this page using similar code.
Do anyone have suggestions what else I could try.
I had to go two iFrames down:
//Parent
browser.switchTo().frame('Iframe1');
//Child
browser.switchTo().frame('Iframe2');
//var NewTextBox = browser.findElement(by.css('.name-textbox')).clear();
var NewTextBox = element.all(by.css('.name-textbox'));
NewTextBox.clear().then(function () {
console.log('Clear text');
Did you tried this way instead of element.all.
element.all return a list elemenet and element return only single element.
var NewTextBox = element(by.css('.workflow-name-textbox'));
or
var NewTextBox = element(by.xpath('//input[#placeholder='Enter Workflow Name']'));