Maybe the question is easy, but I did not find the answer
In my model I have rule:
array('name', 'length', 'max'=>65),
In my view I have code:
$form->textField($model,'name');
After rendering i have:
<input id="name" type="text" value="" maxlength="65" name="name">
Everything fine, but is it possible to get max length property from model on view page?
I what to show max length somewhere on the page, but i can't get this property.
Thanks
Try this:
foreach ($model->getValidators('name') as $validator) {
if ($validator instanceof CStringValidator && $validator->max !== null) {
echo 'this is the max length ' . $validator->max;
break;
}
}
This would return all validators for the 'name' attribute. Then search for the CStringValidator and return the max size.
You could use:
$model->getValidators('name');
which would return you array of validators applied to 'name' attribute. Then find StringValidator and its field named 'max', for this example.
Related
I have the following input
<input
type="text"
:disabled="disabledMoney"
v-model="packageForm.crime.forgeryCrimeSelected"
v-mask="{alias: 'currency', digits:0, min:minMoney, max:maxMoney}"
autofocus
/>
to which I assign the property max:maxMoney of data ();
This input is shown based on a radio button, so when selecting the radio button the input appears and with its correct max value, but if I try to change the max value in a method, the change no longer applies
in the method I just do
change(){
this.maxMoney = 6000 // Assigning new max
}
But it does not apply and stays with its initial value
What you need to do is use a computed value. This will re calculate everytime there is a change in state with the values involved.
Here is some reading from the docs: https://v2.vuejs.org/v2/guide/computed.html
Hey based on your comment, I would do something like this:
<input
type="text"
:disabled="disabledMoney"
v-model="packageForm.crime.forgeryCrimeSelected"
v-mask="{alias: 'currency', digits:0, min:minMoney, max:maxMoneyComp }"
autofocus
/>
computed: { maxMoneyComp(){ return packageForm.crime.forgeryCrimeSelected == 10000 ? 10000:25000; } }
I have an array of names, and if a user try to update one of them and is duplicate, I want to do something (error message) The problem is that is always duplicate. Pname will be changed on every keypress. I am not sure how to store the initial array and to compare with it.
<input
v-model="Pname"
type="text"
class="form-control"
/>
for(let element of this.customer_names){
if(this.Pname == element.name){
duplicateValue = +1;
}
}
You can do something as simple as:
if(this.customer_names.indexOf(this.Pname) != -1) {
// there is a duplicate somewhere
}
Put that code in your change/key-up event listener
You can use #blur like this:
<input
v-model="Pname"
type="text"
class="form-control"
#blur="findDuplicate"
>
function findDuplicate () {
if(this.customer_names.indexOf(this.Pname) != -1) {
// There is a duplicate
}
}
So, by this when you click outside, after you are done with typing, it will run that findDuplicate function.
I am using FluentValidation for the server side validation. Now I want to call a function using must.
This is the form code snippet :
<form method="post"
asp-controller="Category"
asp-action="SaveSpecification"
role="form"
data-ajax="true"
data-ajax-loading="#Progress"
data-ajax-success="Specification_JsMethod">
<input asp-for="Caption" class="form-control" />
<input type="hidden" asp-for="CategoryId" />
<button class="btn btn-primary" type="submit"></button>
</form>
What changes should I make to the code below to call function SpecificationMustBeUnique ?
public class SpecificationValidator : AbstractValidator<Specification>
{
public SpecificationValidator()
{
RuleFor(x => new { x.CategoryId, x.Caption}).Must(x => SpecificationMustBeUnique(x.CategoryId, x.Caption)).WithMessage("not unique");
}
private bool SpecificationMustBeUnique(int categoryId, string caption)
{
return true / false;
}
}
Tips: 1 - The combination of CategoyId and Caption should be unique
2 - Validation is not done when submitting the form(the validation just not running when submit the form)
The tricky part is deciding which property should be validated when the validation rule applies to a combination of values on different fields. I usually just close my eyes, and point to one of the view model properties and say "this is the property I'll attach the validator to." With very little thought. FluentValidation works best when the validation rules apply to a single property, so it knows which property will display the validation message.
So, just pick CategoryId or Caption and attach the validator to it:
RuleFor(x => x.CategoryId)
.Must(BeUniqueCategoryAndCaption)
.WithMessage("{PropertyName} and Caption must be unique.");
The signature for the BeUniqueCategoryAndCaption method would look like:
private bool BeUniqueCategoryAndCaption(Specification model, int categoryId)
{
return true / false;
}
Note: I guessed that the CategoryId property is an int, but you will need to make sure the categoryId argument to BeUniqueCategoryAndCaption is the same type as the CategoryId property in your view model.
My custom filter isn't working. Can anyone please correct me?
In my
public function actionAdmin($mid=null) {
// the appropriate codes here...
$date = ">= ".date("Y-m-d");
$this->render('admin', array(
'model' => $model,
'mid' => $mid,
'date'=>$date,
));
}
In my admin.php, I added this line in the appropriate field, in this case, dateEnd.
UPDATED
array(
'name'=>'dateEnd',
'htmlOptions'=>array('width'=>'150px'),
'filter'=>array('0'=>'', '1'=>$date),
),
Okay, so here's the problem. No matter what I click on, it's not filtering anything. I want it to filter either a blank space OR a date of today.
Can I please know what have I done wrong? Please feel free to correct me. Thanks!
You can't access passed variable inside cgridview. For this purpose, you can define a global variable inside your controller, and access it inside cgridview, something like this:
class Yourcontroller extends Controller {
public $date;
public function actionAdmin($mid=null) {
// the appropriate codes here...
$this->date = ">= ".date("Y-m-d");
$this->render('admin', array(
'model' => $model,
'mid' => $mid
));
}
}
Now, you can access date inside grid:
array(
'name'=>'dateEnd',
'htmlOptions'=>array('width'=>'150px'),
'filter'=>array('0'=>'', '1'=>$this->date),
),
Change this line :
'filter'=>array('0'=>'', '1'=>$date),
To this line:
'filter' => array(">= ".date("Y-m-d") => Yii::t('app', 'Still On Leave')),
Basically the first parameter is the real value, where as the second part is the View to be displayed.
In the First line, '1'=>$date means 1 value but to display a $date field on the CGridView's filter. It will take the value 1 to filter instead of the $date field.
Treat it like the Select element in HTML, where you have this line:
<select>
<option value="1">One</option>
<option value="2">Two</option>
</select>
Javascript basically takes the value instead of the word One being displayed.
This is the same explanation for it.
I am kind of lost on how to do this in my view.
I want to add the quantity. Right now, it adds but how do I get the input value into my ajaxlink?
My controller is using session to add.
<input id="quantity" type="text" value="1" class="span1">
<div id="cart-text">
<?php echo CHtml::ajaxLink(' Add ',
Yii::app()->createUrl('controller/basketAjax',array('id'=>$_GET['id'])),
array('success'=>'function(data){...
controller:
$session=new CHttpSession;
$session->open();
if (!isset(Yii::app()->session['cart']))
{
$quantity = 1;
$session->add('cart',array(
'product_id.'.$id=>array("id"=>$id,
'quantity'=>$quantity)
));
}
else
{
$cart = Yii::app()->session['cart'];
$array = $cart['product_id.'.$id];
if (isset($array)){
$array['quantity']=$array['quantity']+1;
} else {
$t = array('product_id.'.$id=>array("id"=>$id,'quantity'=>$quantity));
array_push($cart,$t);
}
$session->add('cart', $products);
}
you can do this by using keyup function of jquery. First set the id of link as "mylink". Compute the url by using createUrl.
<script type="text/javascript" >
$("#quantity").keyup(function(){
var url=<?php echo Yii::app()->createUrl('controller/basketAjax') ?>;
$("#mylink").attr("href","");
$("mylink").attr("href",url +$(this).val());
});
</script>
Now i explain whats happening above. first i catch the event keyup on input you are using. It will be called each time you press a key on input. Now url=<?php echo Yii::app()->createUrl('controller/basketAjax') ?>; this code is returning you the base url to your action without any parameters being passed.this line $("#mylink").attr("href",""); will set the href of your link to " "( means nothing). Now this line $("mylink").attr("href",url +$(this).val()); is appending the value of the input you are getting from the input.
Remember you have to put the separator in between like
$("mylink").attr("href",url+"/" +"id"+"/"+$(this).val());
Above i have assumed that the href in your case looks like "projectname/index.php/controller/action/id/something". Thats y i have used separators in between but you can customize it according to your needs.
ajaxLink will not work (from what I know), just build it the old fashion way with jquery. Your best solution is actually to put it in a form and submit the form. Something like
<?php
Yii::app()->clientScript->registerCoreScript('yiiactiveform');
$form=$this->beginWidget('CActiveForm', array('action'=>Yii::app()->createUrl('cart/addProduct')));?>
<input type="text" name="quantity" value="1">
<input type="hidden" name="Product_id" value="<?php echo $model->id;?>">
<?php echo CHtml::ajaxSubmitButton('Save',CHtml::normalizeUrl(array('cart/addProduct','render'=>true)),
array(
'dataType'=>'json',
'type'=>'post',
'success'=>'function(data) {
if(data.status=="success"){
$("#formResult").html("form submitted successfully.");
}
else{
$.each(data, function(key, val) {
$("#user-form #"+key+"_em_").text(val);
$("#user-form #"+key+"_em_").show();
});
}
}',
)); ?>
<?php $this->endWidget(); ?><!-- .contact -->
Sorry for the indenting, hard to indent properly here.