Before I started using Vue I had a simple form that would update 1 value on 1 column # 1 request at a time. Now I am using Vue and my form has a new 'middle' button that is being used to build up an array of items to submit 1 request to update multiple columns dynamically.
Problem is now that prevent default is enabled, my original form submission no longer works and I need to either submit the request with Vue or is there a way to re-enable default action on a button? This would be great.
<form #submit.prevent="newbutton">
// new button
<button #click="newbutton"></button>
// original button
<button #click="submit" :id="{{ $element->id }}></button> // #submit.enableDefault ??
The prevent is just a helper method on the #submit. To allow this variance you will need to move the logic into your newbutton method
// in template remove prevent
<form #submit="newbutton" action="/where-this-should-post">
// in script move logic to your newbutton method
methods {
newbutton(event) {
if (formNotValid) {
event.preventDefault()
}
}
}
Related
I have an embedded Marketo form I am using on my site.
When I click submit I want the form to reset to its original state.
What do I need to add to my code for this, and better yet where can I find this in the Marketo documentation?
Here's my current code
<script src="//app-sjg.marketo.com/js/forms2/js/forms2.min.js"></script>
<form id="mktoForm"></form>
<script>
MktoForms2.loadForm("//app-sjg.marketo.com", "819-OWT-537", 1404);
</script>
<script>
MktoForms2.whenReady(function (form){
form.onSuccess(function(values, followUpUrl){
$('#confirmform').modal('show');
return false;
});
});
</script>
The Marketo Form object does not have the reset functionality, but luckily enough, javascript has such a native .reset() method on the HTML form elements. This .reset() method will restore a form element’s default values.
Having said that, the only thing to do within the .onSuccess() callback is to grab the HTML form. Calling the .getFormElem() method of the Marketo Form object, will give us the jQuery wrapped form element, so with form.getFormElem()[0] finally we get the form node, on which we can call .reset().
Here is the sample code:
<script src="//app-lon06.marketo.com/js/forms2/js/forms2.min.js"></script>
<form id="mktoForm"></form>
<script>
// The fourth argument of the `.loadForm()` can be used as an onReady callback.
MktoForms2.loadForm("//app-sjg.marketo.com", "819-OWT-537", 1404, function(form) {
form.onSuccess(function(values, followUpUrl){
// $('#confirmform').modal('show');
console.log(form);
// .getFormElem() returns the jQuery wrapped form element
var formElement = form.getFormElem()[0];
// .reset() is a native javascript method.
formElement.reset();
// If boolean `false` is returned then the visitor
// will NOT be forwarded to the follow up page!
return false;
});
});
</script>
Note: the good thing is, that all the important hidden fields (e.g.: formid and munchkinId) will remain intact.
I am trying to build a small, 3 step form. It would be something similar to this:
The way I did this in react was by using redux to track form completion and rendering the form body markup based on the step number (0, 1, 2).
In angular 2, what would be a good way to do this? Here's what I am attempting at the moment, and I'm still working on it. Is my approach fine? Is there a better way to do it?
I have a parent component <app-form> and I will be nesting inside it <app-form-header> and <app-form-body>.
<app-form>
<app-header [step]="step"></app-header>
<app-body [formData]="formData"></app-body>
</app-form>
In <app-form> component I have a step: number and formData: Array<FormData>. The step is just a index for each object in formData. This will be passed down to the header. formData will be responsible the form data from user. Each time the form input is valid, user can click Next to execute nextStep() to increment the index. Each step has an associated template markup.
Is there a better way to do something like this?
don't overdo it, if it is a simple form you don't need to use the router or a service to pass data between the steps.
something like this will do:
<div class="nav">
</div>
<div id="step1" *ngIf="step === 1">
<form></form>
</div>
<div id="step2" *ngIf="step === 2">
<form></form>
</div>
<div id="step3" *ngIf="step === 3">
<form></form>
</div>
It's still a small template, and you kan keep all of the form and all the data in one component, and if you want to you can replace the ngIf with something that switches css-classes on the step1,2,3 -divs and animate them as the user moves to the next step
If you want to keep things extensible, you could try something like this:
<sign-up>
<create-account
[model]="model"
[hidden]="model.createAccount.finished">
</create-account>
<social-profiles
[model]="model"
[hidden]="model.socialProfiles.finished">
</social-profiles>
<personal-details
[model]="model"
[hidden]="model.personalDetails.finished">
</personal-details>
</sign-up>
export class SignUpVm {
createAccount: CreateAccountVm; //Contains your fields & finished bool
socialProfiles: SocialProfilesVm; //Contains your fields & finished bool
personalDetails: PersonalDetailsVm; //Contains your fields & finished bool
//Store index here if you want, although I don't think you need it
}
#Component({})
export class SignUp {
model = new SignUpVm(); //from sign_up_vm.ts (e.g)
}
//Copy this for personalDetails & createAccount
#Component({})
export class SocialProfiles {
#Input() model: SignUpVm;
}
what is the best way to clear bootstrap modal form data without using jquery?
I could use this, but I would like to know the angular way of clearing modal form data.
$('#myModal').on('hidden', function () {
$('#Username').val("");
});
Edit:
I have multiple elements on the form. I found out the easiest way is to create a service to reset the object and updates the ng-models on the form.
To reset the form object, call the shared service to reset: mySharedService.resetObj(); To clear the form in controller:
$scope.myObj = mySharedService.getObj();
$scope.myForm={};
$scope.myForm.myData = angular.copy($scope.myObj);
all the elements is under the 'myData' item.
Use ng-bind to set the value of whatever inside the <div class="modal-body"> equal to a $scope variable, then change the $scope variable on whatever action you want, most likely on the cancel event, like so:
$scope.cancel = function () {
$scope.yourVariable = "";
$modalInstance.dismiss('cancel');
};
the binding is like this:
<div class="modal-body">
<div ng-bind="yourVariable"></div>
</div>
I'm building a "buffet menu list" form which has a lot of options for the "menu" radiobutton.
However I noted that all those values are "inline" just like in this example: http://demo.atk4.com/demo.html?t=14
I'd like to know in first instance how could I add a line break on every value, and then, how could I simulate groups by adding some sort of < p> < /p> between specific option values (logical grouping).
Thanks in advance!
There are two solutions I can think of.
Look at the examples here for some inspiration:
http://agiletoolkit.org/doc/grid/columns
1. Adding custom field to grid
First, create a form with no mark-up:
$form = $this->add('Form',null,null,array('form_empty'));
Next, add Grid into a form like this:
$grid = $form->add('Grid'); // or MVCGrid if you are using models
Add a column for selection:
$grid->addColumn('template','selection')
->setTemplate('<input type=radio name=selection value="<?$id?>"/>');
Finally - make sure the column 'selection' is first (or last)
$grid->addOrder()->move('selection','first')->now();
Finally you need to manually look into the POST data, because it's not a real form column.
if($form->isSubmitted()){
$this->js()->univ()->successMessage('Selection is '+((int)$_POST['selection']))
->execute();
}
You must remember that accessing POST directly exposes you to injection attack and you must validate it properly. Grid also MUST be inside the form, however you can place submit button anywhere else on your page. You can also use "Form_Plain", see "http://agiletoolkit.org/whatsnew" for an example.
2. Using JavaScript and hidden field
In this example you can add a bunch of Radio button elements and tie them to a form. I've also using "Lister" here instead of "Grid", of course you can mix-and-match those approaches.
$form = $this->add('Form');
$selection = $form->addField('line','selection');
// can be placed anywhere.
$menu = $this->add('MVCLister',null,null,array('view/menu'));
$menu->setModel('MenuItems');
$menu->js(true)->find('input[type=radio]')->click(
$selection->js()->_enclose()->val(
$this->js()->_selectorThis()->val()
);
);
// produces $('#menu_id').find('input[type=radio]').click(function(){
// $('#selection_id').val( $(this).val() );
// }
Your view/menu.html template file could look like this:
<div class="menu-container">
<?rows?><?row?>
<div><input type="radio" name="anything" value="<?$id?>"> <?$name?> </div>
<?/row?><?/rows?>
</div>
EDIT: code which worked for Fernando
$grid->addColumn('template','Menu')
->setTemplate('<input type=\'radio\' name=\'selection\' value="<?$value?>"/> <?$value?>');
if($form->isSubmitted()){
$this->js()->univ()
->successMessage('Hoy: <b>'.$_POST['selection'].'</b>')->execute();
}
I am getting re-execution of imported js files upon a hitting a form button which calls a function to insert a DOM element into page ( in simulation to exe of an ajx callback function). The DOM insertion causes a page refresh which re-requests all files from server.
Nothing big on the function call:
var addFashionVideo = function() {
var nodeContainer = document.getElementById('vidList');
var mytitle = document.forms.addVideo.newVidName.value;
var addTextNode = document.createTextNode(mytitle);
var newLI = document.createElement('LI');
newLI.appendChild(addTextNode);
nodeContainer.appendChild(newLI);
return this;
};
TARGET DIV for DOM update code is :
<div id="ajParent" class="aj" style="width:325px;background-color:blue;color:white;">
<ul id="vidList">
<li>Watch Fashion Paris Video</li>
</ul>
</div>
I place an alert on this page and after the function attempts to insert the new LI
[ oddly the LI appears for a split second then disappears ] a page refresh is triggered
and my alert on the page re-executes.
// Perhaps Maybe I have a browser issue on this computer or I am just to new of a scripter
// to not see the problem...any comment appreciated.
The minute you hit submit on a form, the page will reload since you have made a GET request with the form. In order to stop the form from submitting you would have to make it return false on submit. e.g.
document.getElementById('formname').onsubmit = function {
return false;
};
You would have to make sure to disable form submission so the page doesn't reload, then you could run your ajax request on submission and do what you must on success in the ajax function.
I really doubt your dom insertion is causing the reload.