How to initiate an action to `component` from `Router` - validation

In my page, the router taking care of page transition. but before i go for next page, I would like to validate the form fields. for that I use the cp-validation addon.
But when the next button clicked, I would like to ask my child component to do the validation and send back the result to router. how to do this?
I tried to validate the model within router but not works. if my try is not correct way please let me know the correct approach to handle this scenario.
my router bhs:
<div class="balanceEmi rdc-scroll-content has-subheader rdc-view">
{{cs2i-select-tenure selectedCreditCard=model}}//my component
//which requie to know the form validation
</div>
<div class="rdc-view___footer rdc-view___footer---stickey">
{{rdc-button default="CANCEL" type="secondary" action="redirect"}}
{{#if enableNext}}
{{rdc-button default="NEXT" type="primary" action="goToNext"}}
{{else}}
{{rdc-button default="NEXT" type="primary" disabled="true"}}
{{/if}}
<div class="formValidateBeforeNextBtn" {{action 'formValidateBeforeNext'}}>//let this actin call my component to do the validaiton else le tme know the correct way
<!-- empty for validation button-->
</div>
</div>

I recommend registering the validate component to a factory, then you can call this from wherever you are in your application like a router.
Read the Ember.js docs here

Related

Laravel Livewire/AlpineJS: Disable a button while loading data from an API and then enabling it again

This should be really simple, but I don't get it. I want to replicate the functionality of a button that when pressed goes to an API (which could take about a minute to get the data and process it), it gets diabled, and after loading the data it gets enabled.
I'm using Laravel/Livewire/Alpine
So, in my livewire component I have:
public $loading = false;
In my blade file, I have the declaration for the div where the button is:
<div
class="grid grid-cols-3 gap-4"
x-data="{
loading: #entangle('loading')
}"
>
Then the button x-binds the disabled property to the loading value, when the button is clicked, it changes the property of the loading variable, and calls the loader function
<button
type="button"
class="btn btn-sm btn-jbn"
x-on:click="loading = true"
x-bind:disabled="loading"
wire:click="loader"
>
Load API
</button>
And it does what it is supposed to do... the button is grayed, it becomes unusable, the cursor change, etc., it executes the loader function in my livewire component, but it never return to the normal state after loading the API. In my livewiere componente I have:
public function loader() {
// API call and logic goes here, this works
$this->loading = false;
}
So I would imagine that at the end of the API process the entangled variable loading would return the button to its normal state, but it doesn't
What am I missing?
Livewire already has incorporated functionality to handle loading-states. Instead of implementing your own, you can use this.
Get rid of all your current loading-logic, and simply use wire:loading with wire:target on your button.
wire:loading can toggle the disabled attribute directly by doing wire:loading.attr="disabled", and wire:target is to set the target for that loading-state to the method you are calling, so in your case that's wire:target="loader".
This means your button looks like this,
<button
type="button"
class="btn btn-sm btn-jbn"
wire:click="loader"
wire:loading.attr="disabled"
wire:target="loader"
>
Load API
</button>

inivisible Google ReCaptcha Integration with Knockout and AJAX Post

I am trying to integrate the Google Invisible Captcha to my contact form. The integration is working to an extent and I can submit my form and the challenge appears.
However, I assumed that the data-callback added to the div would call my submit function again after the challenge is completed? So currently I have to click the form submit button a second time after the challenge is completed?
I have added the following to my contact form (reduced for brevity);
<div class="col-md-12">
<div class="g-recaptcha"
data-sitekey="mykey"
data-callback="submitForm"
data-size="invisible"
data-bind="formSubmitButton">
</div>
</div>
<div class="col-sm-12 text-center">
<input id="formSubmitButton" data-bind="click: submitForm" type="button" class="btn btn-primary btn-block btn-lg" value="Send Enquiry" />
</div>
and in my submitForm method I have the following code;
this.submitForm = function () {
...
//if no field error validate captcha
if (!error) {
//validate captcha
var response = grecaptcha.getResponse();
if (response.length == 0) {
grecaptcha.execute();
return;
}
}
...
}
I am correct in thinking that I shouldn't need to submit the form a second time? and if so what is it I am doing wrong here please.
You shouldn't need to submit the form twice.
I posted an answer to a similar question about setting up recaptcha with a knockout ajax request.
You may need to restructure how you are setting up your form and functions. I found that you can set up a jquery function to use as the required callback function, that calls your knockout ajax request. Set your button or hidden div to send that as the callback function. I found success by using a button.
You only need to click the button, which does its recaptcha thing (sends a request to google, and then saves its response, which can by accessed later), which then calls your callback function you gave it, which calls your original knockout ajax request. That request will work normally as it did before recaptcha was added, but you will send your recaptcha response like you were getting with: var response = grecaptcha.getResponse(); so your server can validate it.
The link I proved has a more detailed answer, I hope this helps.

Angular 2 form valid by default

Having issue with form validation .
i want to submit the form only when form is valid.
but with the empty inputs and clicking on submit button is submitting the form although the inputs are empty.
<form name="equipmentForm" #f="ngForm" (ngSubmit)="f.form.valid && addEquipment()" validate>
Inputs be like this.
<input name="equimentId" class="text-input form-control" type="text" [(ngModel)]="model.equipmentNumber" pattern="^[0-9][0-9]{1,19}$" title="Equipment ID. can be upto 20 digits only.">
I cant post the whole code although.
this
f.form.valid is true from form initialization
wanted to acheive something like this
<div *ngIf="!model.equipmentModel && f.submitted" class="text-danger">
Please enter Equipment Model
</div>
So on submit i want to show this message instead of default browser's.
but this f.form.valid is goddamn true from default.
You should add required attribute to your input tags to, then as #Cobus Kruger mentioned, form will not be submitted untill it is filled.
However you can also give a try to pristine, dirty options, which allow you to check if the user did any changes to the form so in this case your condition may look like this:
<form name="equipmentForm" #f="ngForm" (ngSubmit)="f.form.valid && f.form.dirty ? addEquipment() : ''" validate>
and the input:
<input name="equimentId" class="text-input form-control" type="text" [(ngModel)]="model.equipmentNumber" pattern="^[0-9][0-9]{1,19}$" title="Equipment ID. can be upto 20 digits only." required />
In this case it will check if any changes were applied to the input, and submit the form if both conditions are met.
If you specify the required attribute on the input, then the form will not be submitted unless a value is filled in. But that only covers values that were not supplied and you may want to check for invalid values as well.
The usual way is to disable the submit button unless the form is valid. Like this:
<button type="submit" [disabled]="!f.form.valid">Submit</button>
The Angular documentation about form validation also shows this. Look near the bottom of the "Simple template driven forms" section
In function which you call on submit you can pass form as parameter and then check. In html you will need to pass form instance:
<form name="equipmentForm" #f="ngForm" (ngSubmit)="addEquipment(f)" validate>
In typescript:
addEquipment(form){
if(form.invalid){
return;
}
//If it is valid it will continue to here...
}

Scripts not working on partial view after Ajax call

I have called scripts on _Layout.cshtml page and my Index.cshtml page has partial view into it. So on page load, SignalR scripts working perfect on partial view, on page end I make another ajax request and load the partial view with another data filled in that and embed under already displayed data, and then the SignalR does not work on the newly embedded record.
This is my index page code:
<div class="col-md-6">
<div class="profile-body">
<div class="row infinite-scroll">
#Html.Partial("_AlbumRow", Model)
</div>
</div>
</div>
This is my partial View Code:
#model IEnumerable<SmartKids.Lib.Core.ViewModels.FileMediaAlbumsVM>
#foreach (var item in Model)
{
<div class="widget">
<div class="block rounded">
<img src="#Url.Content(item.ImageUrl)" alt="#item.Title">
<input type="button" data-image-id="#item.imageId" class="btn btn-sm btn-default">Like</input>
</div>
</div>
}
Kindly help me how to resolve this issue that after making an ajax request I am not able to get those SignalR working. Here is more to say when I put the SignalR scripts on PartialView that works but it also sucks that on each ajax request there is again SignalR loaded on the page and when I click on LIke button it makes many calls to the function behind it.
Kindly help me to resolve this issue, I am stuck at this point since 1 week.
Here is signalR Code:
$(".btn.btn-sm.btn-default").on("click", function () {
var imageId = $(this).attr("data-image-id");
albumClient.server.like(imageId);
});
Problem: You are binding event to elements directly, So when you remove this element and replace it with a different one the events are also removed along with that element, This is something like strongly coupled.
Solution: Use Jquery event delegation. This will make sure the events will be triggered on the current elements and also all the elements that can come in future.
syntax is as below.
$(document).on("click", ".btn.btn-sm.btn-default",function () {
var imageId = $(this).attr("data-image-id");
albumClient.server.like(iamgeId);
});
NOTE: This was never a singlaR issue, it was Jquery issue.
Efficient Way: The problem in using $(document).on("click"... is that when ever there is a click happening on the entire page the Jquery framework will bubble the events from the clicked element upwards(its parent, and its parent and so on..) unless the element specified in the selector arrives, So its kind of performance hit as we don't want this check's to run if we are clicking outside the required area ( button .btn.btn-sm.btn-default in this example).
So best practice is to bind this event delegation to the closest parent possible which will not be removed, <div class="row infinite-scroll"> in this question. So that only when the click happens within this element the event bubbling will happen and also will be stopped once it reaches the parent element,it acts kind of a boundary for event bubbling.
$('.row.infinite-scroll').on("click", ".btn.btn-sm.btn-default",function () {
var imageId = $(this).attr("data-image-id");
albumClient.server.like(iamgeId);
});

How to clear selected value from Bootstrap FormHelpers SelectBox

How does one access the various options for the bootstrap formhelpers library?
I have tried every way of accessing them, but get an error every time.
Specifically, I'm trying to clear out the selected value in a bfh-selectbox
$("#Select").val('');
$("#Select").selectpicker("refresh");
see How to reset value of Bootstrap-select after button click
Its hard to clear the value of a select box since its a dropdown. Do you mean setting the dropdown to a specific option?
For your specic question: You can set and get the value of the bfh-selectbox with JQuery like this:
HTML:
<div id="selBox" class="bfh-selectbox" data-name="selectbox1">
<div data-value="1">Option 1</div>
<div data-value="2">Option 2</div>
<div data-value="3">Option 3</div>
</div>
Get value:
var output = $("#selBox").val();
Set value:
$("#selBox").val([Replace with valid option value]);
BFH are great components, but their documentation is really lacking.

Resources