How can I pass a param to a custom validator? - javascript

I have the below custom validator, which is working great when passed to my input like this:
<select id="salesOwnerIdInput" v-model="currentCompany.salesOwnerId" name="salesOwnerId"
v-validate.immediate="{ 'required': salesOwnerRequired, 'contains': !userHasPlanAccess }"
:class="{'form-control': true, 'is-invalid': errors.has('main-tab.salesOwnerId') }"
data-vv-as="Sales Owner"
data-vv-scope="main-tab">
<option value="">- Select -</option>
<option v-for="option in ownerList" v-bind:value="option.id" v-bind:key="option.id">
{{ option.name }}
</option>
</select>
But as soon as I try to add a param
v-validate.immediate="{ 'required': salesOwnerRequired, 'contains:test': !userHasPlanAccess }"
I get this stupid error
vee-validate.esm.js:290 Uncaught (in promise) Error: [vee-validate] No such validator 'contains:test' exists.
What am I doing wrong??
const ContainsValidator = {
params: [
'message'
],
getMessage(field, args) {
return 'get message from args';
},
validate(value, args) {
return false;
}
}
I tried adding the param name to my registration, but it has no effect - I'm not sure if this even makes sense?
VeeValidate.Validator.extend("contains", ContainsValidator, { paramNames: ['message'] });
I am using vee-validate 2.1.4

I managed to solve it by calling the validator like this
v-validate.immediate="`required:${salesOwnerRequired}|contains:testMessage,${salesOwnerHasPlanAccess}`"
So passed the entire ruleset as a string, and interpolated anything that needed to be passed down

Related

vuejs - bootstrap-select options not working

I have this select:
<select v-model="filterState" #change="search()" class="selectpicker livesearch form-control" ref="stateSelect" id="stateSelect">
<option value="">Alle Status</option>
<option v-for="assignmentState in assignmentStates" v-bind:value="assignmentState.state">
{{ assignmentState.state }}
</option>
</select>
It will only work when I refresh it like this:
export default {
name: "AssignmentList",
data() { ....
},
updated() {
$(this.$refs.stateSelect).selectpicker('refresh');
}
But with this method the options like "livesearch" didn't work.
// Select2 Livesearch
$('.livesearch').selectpicker({
liveSearch: true,
noneSelectedText: 'Nichts ausgewählt',
});
I can enable the livesearch only with the "data-live-search" attribute like this:
<select v-model="filterState" #change="search()" data-live-search="true" class="form-control" ref="stateSelect" id="stateSelect">
But I want to set the options in my JS file without using the data attributes.
How can I did this?
first thing in your v-for you need to bind a key, see the doc for better explanation.
second advice, if you can, don't mix jquery with vue, you don't need to do that, eg:
$(this.$refs.stateSelect).selectpicker('refresh');
can be:
this.$refs.stateSelect.selectpicker('refresh'); // this can be wrong because selectpicker need a jquery object, but se the logic XD
i don't understand very well wich is your purpose, but i think you can use the watch hook:
watch: {
filterstate(){//v-model of select
$('.livesearch').selectpicker({
liveSearch: true,
noneSelectedText: 'Nichts ausgewählt',
});
}
}
with vue for the ui you can use bootstrap-vue or vuetify

Why if I get the object property within the computed object gets undefined but not the object itself? Which approach fits better in this context?

My Greeting.
To put in context, my purpose of asking this question is to be able to render a child component inside a form based on the selected option of the <app-selector> Vue component as simple and silly as that.
For the sake of simplicity. I've made a snippet down here to expose what I'm trying to figure out.
Basically, the aim is to get the component name to be rendered by using the computed property cardTypeComponent. However, I want to fathom the way cardTypeComponent is working, since I cannot see why, in one hand, the first return (return this.form) is giving the object (this.form) with the property I want (card_type) but on the other hand the second return (return this.form.card_type ? this.form.card_type + 'Compose' : '') is giving me an empty string, assuming this.form.card_type is undefined when it is clear looking at the first return that, in fact, is not taking it as undefined.
There is way more context, since once the option is selected there is a validation process from the server before setting the value inside this.form object. Moreover, the form interaction is through steps, so once the user select the option he has to click a button to reach the form fields that corresponds to that type card selected, therefore the component is not going to be rendered the very first moment the user selects an option as in the snippet approach. However, it would entangle what I'm asking. Thanks beforehand.
It is better to use the Fiddle link below.
Snippet
var appSelector = Vue.component('app-selector', {
name: 'AppSelector',
template: `<div>
<label for="card_type">Card Type:</label>
<select :name="name" value="" #change="sendSelectedValue">
<option v-for="option in options" :value="option.value">
{{ option.name }}
</option>
</select>
</div>`,
props: {
name: {
required: false,
type: String,
},
options: {
required: false,
type: Array,
}
},
methods: {
sendSelectedValue: function(ev) {
this.$emit('selected', ev.target.value, this.name)
}
}
});
var guessByImageCompose = Vue.component({
name: 'GuessByImageComponse',
template: `<p>Guess By Image Compose Form</p>`
});
var guessByQuoteCompose = Vue.component({
name: 'GuessByQuoteComponse',
template: `<p>Guess By Quote Compose Form</p>`
});
new Vue({
el: '#app',
components: {
appSelector: appSelector,
guessByImageCompose: guessByImageCompose,
guessByQuoteCompose: guessByQuoteCompose,
},
data() {
return {
form: {},
card_types: [
{
name: 'Guess By Quote',
value: 'GuessByQuote'
},
{
name: 'Guess By Image',
value: 'GuessByImage'
}
],
}
},
computed: {
cardTypeComponent: function() {
return this.form; // return { card_type: "GuessByImage" || "GuessByQuote" }
return this.form.card_type ? this.form.card_type + 'Compose' : ''; // return empty string ("") Why?
}
},
methods: {
setCardType: function(selectedValue, field) {
this.form[field] = selectedValue;
console.log(this.form.card_type); // GuessByImage || GuessByQuote
console.log(this.cardTypeComponent); // empty string ("") Why?
}
},
mounted() {
console.log(this.cardTypeComponent); // empty string ("")
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<form action="#" method="post">
<app-selector
:name="'card_type'"
:options="card_types"
#selected="setCardType"
>
</app-selector>
{{ cardTypeComponent }} <!-- Always empty string !-->
<component v-if="cardTypeComponent !== ''" :is="cardTypeComponent">
</component>
</form>
</div>
https://jsfiddle.net/k7gnouty/2/
You're setting a property on this.form which is not initialized first in data. This means you have run into Vue's change detection caveat. Use Vue.set when setting it:
methods: {
setCardType: function(selectedValue, field) {
Vue.set(this.form, field, selectedValue);
}
}
Alternatively, you could declare the properties first if that works better for you.

Changing exists rule based on choosen option

So i have this simple code to input value based on database value in registration form and it's work great,
The code below located at register.blade.php
This for selecting branch
<div class="form-group form-material floating">
<select class="form-control" name="branch" id="branch">
<option value="1">Option A</option>
<option value="2">Option B</option>
</select>
<label class="floating-label" for="inputStatus">Branch</label>
</div>
This one for inputing reference
<div class="form-group form-material floating {{ $errors->has('reference') ? ' has-error' : '' }}">
<input type="text" class="form-control empty" id="reference" name="reference">
<label class="floating-label" for="inputStatus">Reference</label>
#if ($errors->has('reference'))
<span class="help-block">
<strong>{{ $errors->first('reference') }}</strong>
</span>
#endif
</div>
the code below located atRegisterController.php
And this one for validation
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'phone' => 'required|string|min:5|max:20',
'rate' => 'required',
'product' => 'required',
'branch' => 'required',
'reference' => [
'required',
Rule::exists('references')->where(function ($query) {
if( 'branch' == 1 ){
$query->where('references.type', '=', "TOP");
}
else{
$query->where('references.type', '=', "BOTTOM");
}
}),
],
]
);
}
In registration form when user choose the first option on branch, the user can only write (Example : 'ABC', 'DEF', 'GHI') if the user write another value it will return Error Message : 'Wrong reference code', but when the user choose second option on branch, the user can only write (Example : '123', '456', '789'), , does anyone have and idea how to do it? Thanks
Edit 1 :
The code above works fine, but the exists rule for reference is not working, user still able to input 'ABC', 'DEF', or 'GHI' when choosing second option.
Edit 2 :
I also have this custom validation inside register.blade.php
fields: {
reference: {
validators: {
notEmpty: {
message: 'Reference must be filled'
},
stringLength: {
max: 8,
message: 'Max 8 character'
}
}
}
}
For this you need Custom Validation .Custom Validation . and about query, you can do that inside
public function passes($attribute, $value){
//value will have your reference value
//Logic here and return true/false
}
public function message()
{
//error message
//return "The :attribute value doesnt exist.";
}
and if you want to pass parameters in custom rule then you need to use constructor and use it . i.e
protected $customParams;
public function __construct($customParams)
{
$this->customParams = $customParams;
}
and rules would look like this
'reference' => ['required',new CustomRule('customvalue')]
Hope this helps.
You can make custom validation. So you can move this extra validation inside your custom validation. May be it can solve your problem.
Refer this for more on custom validation: Laravel custom validation
Hope it helps:)

how to set combo box default value as session logged in user id in sap ui5

I am using comboBox control in sap ui5. I need to show default logged in user id. How can I achieve so?
This default user id is the part of odata service. For example I have 10 data(INC0001 to INC0010). If user INC0004 logged in then by default I want to show that in the comboBox. I am getting only first blank right now.
XML Code :
<Select id="select1"
items="{ path: '/UserSet', sorter: { path: 'zuserid' } }"
change="handleChange">
<core:Item text="{zuserid}" key="{zuserid}"/>
<layoutData>
<l:GridData span="XL2 L2"/>
</layoutData>
</Select>
Session user in sap ui5:
var userId = sap.ushell.Container.getService("UserInfo").getUser().getId();
Have you tried binding the data in your controller?
this.getView().byId("select1").bindItems({
path: "/UserSet",
template: new sap.ui.core.Item({
key: "{zuserid}"
text: "{zuserid}"
}),
events: {
dataReceived: function () {
var userId = sap.ushell.Container.getService("UserInfo").getUser().getId();
this.getView().byId("select1").setSelectedKey(userId);
}.bind(this)
}
});
The event dataReceivedis triggered once the data is received and at that point it is possible to set the selected key of your ComboBoxas #Jorg proposes in the reaction above.
Select has a parameter called selectedKey you can use for this. Usually this is another model binding but you can do it programmatically as well.
The SDK has an example: https://sapui5.netweaver.ondemand.com/sdk#/entity/sap.m.Select/sample/sap.m.sample.Select/code
<Select
forceSelection="false"
selectedKey="{/SelectedProduct}"
items="{
path: '/ProductCollection',
sorter: { path: 'Name' }
}">
<core:Item key="{ProductId}" text="{Name}" />
</Select>
This is the solution for this issue.
This will help anyone is looking out for the same.
var oData ={
recipient :{
name :"TCS0001"}};
var oModel =newJSONModel(oData);
this.getView().setModel(oModel,"NamedModel");
<ComboBox id="combo1" selectedKey="{NamedModel>/recipient/name}" items="{ path: '/UserSet', sorter: { path: 'zuserid' } }" change="handleChange">
<core:Item text="{zuserid}" key="{zuserid}"/>
<layoutData>
<l:GridData span="XL3 L3"/>
</layoutData>
</ComboBox><br>

ng-model for select with defined options

I've got a plain select control in my angular app. When page loads I've got no element selected in select control but if I check $scope.data.Method I've got a correct value in int. Is there any way to fix this issue?
<div class="form-group">
<label class="col-sm-3 control-label">Selected Method:</label>
<div class="col-sm-4">
<select class="form-control" ng-model="data.Method">
<option value="0">Auction</option>
<option value="1">Delivery</option>
<option value="2">Range Delivery</option>
<option value="3">Broadcast</option>
<option value="4">Self broadcast</option>
<option value="5">Manual</option>
<option value="6">Automated</option>
</select>
</div>
</div>
Controlers use service to get data. Here is service code for getting data
//Initialize Resource
this.initResource = function (params) {
params = params || {};
params.id = '#id';
this.resource = $resource('{0}/:id'.format(this.api), params, {
'update': { method: 'POST' },
'create': { method: 'PUT' },
'default': { method: 'GET', params: { id: 'default' } }
});
}
//...more code
//Get some data and initialize additional parameters
this.read = function (id, clone, readonly, version) {
if (clone == undefined)
clone = false;
if (readonly == undefined)
readonly = false;
if (this.resource == null) {
this.initResourceByDefault();
}
return this.resource.get({ id: id, clone: clone, readonly: readonly, version: version });
}
Controller code
function ItemController($scope, $route, $routeParams, $location, $resource, MainCRUDService, ControllerHelper) {
$scope.noticeType = $routeParams.noticeType;
MainCRUDService.initResource({ noticeType: $scope.noticeType });
//Here I am getting data from resourse via service
ControllerHelper.initCRUD($scope, MainCRUDService);
}
As I can understand your problem, your service is returning data.Method as an integer value.
But select box will match a string value.
Your problem will get solved if your service will return data.Method as string. Also you can convert your response paramter data.Method to a string value, by using toString() method.
Here is a plunker code which may help you.
https://plnkr.co/edit/s0Wrk4?p=preview

Categories