I am trying to use this object item.isRequired to set the HtmlAttributes as required but its not working. It work fine when I use the string value in the HtmlAttributes but not when I use the htmlAttributesData string.
var htmlAttributesData = item.isRequired ? "new { required = 'required', data_val_required = 'Question is Required' }" : "";
#(Html.Kendo().RadioGroupFor(m => m.MeetingPollingQuestions)
.Name(string.Format("PollingResponses[{0}].Value", idx))
.HtmlAttributes(htmlAttributesData)
.Items(i =>
{
foreach (var option in #item.RadioButtonList)
i.Add().Label(option.Label).Value(option.Value);
}
)
.Value("Value")
);
The Html.Kendo() code wrapped in #() is processed on the server to generate javascript before the page is sent to the browser. When the server does this, htmlAttributesData does not exist because that is javascript code as far as I can tell. The server does not execute any javascript logic, it simply sends it to the browser.
Two options:
Don't use the Html.Kendo server wrapper and instead use the query plugin syntax to declare the radio group with javascript. That will be processed on the browser where you can then use htmlAttributesData to set it up because it will exist at that point.
Declare htmlAttributesData using server code. Maybe something like:
.HtmlAttributes(#item.isRequired ? new { required = 'required', data_val_required = 'Question is Required' } : null)
Related
I've identified several of my views that require some simple logic, for example to add a class to a set of controls created with #Html helpers. I've tried several different ways, but they either throw errors in the View or just don't work.
A simple example:
Assign variable:
#if( condition )
{
var _disabled = "disabled";
}
#Html.CheckBoxFor(m => m.Test, new { #class = "form-control " + #_disabled })
Or:
#if( condition )
{
var _checked = "checked";
}
#Html.CheckBoxFor(m => m.Test, new { #checked = #_checked })
Of course, these doesn't work. I'm just trying to eliminate a bunch of #if conditions in my Views, but I have other lightweight logic uses for using variables. My problem might be more of how to use a variable in this way than actually assigning it?
It would seem that you're understanding razor fine.
The problem with your code seems to be that you're using a variable out of scope. You can't define a variable inside an if statement, and then use it outside, because the compiler won't know for sure that the variable outside actually exists.
I would suggest the following:
#{
var thing = "something";//variable defined outside of if block. you could just say String something; without initializing as well.
if(condition){
thing = "something else";
}
}
#Html.Raw(thing);//or whatever
As a side note, (in my opinion) it's better to do stuff in the controllers when you can, rather than the views. But if things make more sense in the views, just keep them there. (-:
Hope this helps.
Try this;
#{
var disabled = string.Empty;
if (true)
{
disabled = "disabled";
}
}
#Html.CheckBoxFor(m => m.RememberMe, new { #class = "form-control " + disabled })
Thanks!
I work with Laravel 4.
I want to use the HTML::linkAction to provide a link embedded in an image.
The method's prototype is :
linkRoute( string $name, string $title = null, array $parameters = array(), array $attributes = array() )
Then I use the image method to get my <img></img> code :
HTML::linkAction('contact#index', HTML::image('images/contact.png', 'contact'));
It works almost fine. The problem is that the <img></img> code is formatted like htmlspecialchars() do.
Is there a way to allow HTML code in parameters, or to deactivate the htmlspecialchars fonctionality ? Or maybe it's a bad practice ?
Thanks,
Raphaël N.
You cannot pass HTML to linkAction(), because it internally calls:
$this->entities()
Here is the code for link(), wich is used by linkAction():
public function link($url, $title = null, $attributes = array(), $secure = null)
{
$url = $this->url->to($url, array(), $secure);
if (is_null($title) or $title === false) $title = $url;
return '<a href="'.$url.'"'.$this->attributes($attributes).'>'.$this->entities($title).'</a>';
}
And there is no options to do it differently.
So if you need to pass an image, you'll have to write HTML for that particular link.
I have multiselect jquery plagin (Choosen) and when I use it in 'Multiple Select' mode I expect in controller next values:
posted string = 'value1,value2...'
really have
posted string = 'value2'
only if I reffer directly to FormCollection I'll get expected values as below:
[HttpPost]
public ActionResult TagSearech(/*string tagSelect*/FormCollection c)
{
// only one value here
// string[] names = tagSelect.Split(',');
// as expected: value1,....
string expectedValue = c['tagSelect'];
return View();
}
I cant understand what might cause this behavior.
EDIT
Here is View:
#using (Html.BeginForm("TagSearech", "Tag"))
{
#Html.DropDownList("tagSelect", Model, new { #class = "chzn-select", data_placeholder = "tag names", multiple = "" })
<input type="submit"/>
}
MVC will attempt to bind the input data on the URL into the model. I haven't seen how Chosen.js posts the data back to the server, but essentially its coming in in the wrong format, so MVC binds the first element it sees to the string Model.
The FormsCollection retrieves all of the data that was posted in the URL, which is why all of your selected values can be seen there.
Did you try changing the incoming model from string to string[], and see if all of the items are bound to the array?
So far, I have figured out how to return a typical JSON response in Zend Framework 2. First, I added the ViewJsonStrategy to the strategies section of the view_manager configuration. Then, instead of returning a ViewModel instance from the controller action, I return a JsonModel instance with all my variables set.
Now that I've figured that piece out, I need to understand how to render a view and return it within that JSON response. In ZF1, I was able to use $this->view->render($scriptName), which returned the HTML as a string. In ZF2, the Zend\View\View::render(...) method returns void.
So... how can I render an HTML view script and return it in a JSON response in one request?
This is what I have right now:
if ($this->getRequest()->isXmlHttpRequest()) {
$jsonModel = new JsonModel(...);
/* #todo Render HTML script into `$html` variable, and add to `JsonModel` */
return $jsonModel;
} else {
return new ViewModel(...);
}
OK, i think i finally understood what you're doing. I've found a solution that i think matches your criteria. Though i am sure that there is room for improvement, as there's some nasty handwork to be done...
public function indexAction()
{
if (!$this->getRequest()->isXmlHttpRequest()) {
return array();
}
$htmlViewPart = new ViewModel();
$htmlViewPart->setTerminal(true)
->setTemplate('module/controller/action')
->setVariables(array(
'key' => 'value'
));
$htmlOutput = $this->getServiceLocator()
->get('viewrenderer')
->render($htmlViewPart);
$jsonModel = new JsonModel();
$jsonModel->setVariables(array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1,2,3,4,5,6)
));
return $jsonModel;
}
As you can see, the templateMap i create is ... nasty ... it's annoying and i'm sure it can be improved by quite a bit. It's a working solution but just not a clean one. Maybe somehow one would be able to grab the, probably already instantiated, default PhpRenderer from the ServiceLocator with it's template- and path-mapping and then it should be cleaner.
Thanks to the comment ot #DrBeza the work needed to be done could be reduced by a fair amount. Now, as I'd initially wanted, we will grab the viewrenderer with all the template mapping intact and simply render the ViewModel directly. The only important factor is that you need to specify the fully qualified template to render (e.g.: "$module/$controller/$action")
I hope this will get you started though ;)
PS: Response looks like this:
Object:
html: "<h1>Hello World</h1>"
jsonArray: Array[6]
jsonVar1: "jsonVal2"
You can use more easy way to render view for your JSON response.
public function indexAction() {
$partial = $this->getServiceLocator()->get('viewhelpermanager')->get('partial');
$data = array(
'html' => $partial('MyModule/MyPartView.phtml', array("key" => "value")),
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1, 2, 3, 4, 5, 6));
$isAjax = $this->getRequest()->isXmlHttpRequest());
return isAjax?new JsonModel($data):new ViewModel($data);
}
Please note before use JsonModel class you need to config View Manager in module.config.php file of your module.
'view_manager' => array(
.................
'strategies' => array(
'ViewJsonStrategy',
),
.................
),
it is work for me and hope it help you.
In ZF 3 you can achieve the same result with this code
MyControllerFactory.php
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$renderer = $container->get('ViewRenderer');
return new MyController(
$renderer
);
}
MyController.php
private $renderer;
public function __construct($renderer) {
$this->renderer = $renderer;
}
public function indexAction() {
$htmlViewPart = new ViewModel();
$htmlViewPart
->setTerminal(true)
->setTemplate('module/controller/action')
->setVariables(array('key' => 'value'));
$htmlOutput = $this->renderer->render($htmlViewPart);
$json = \Zend\Json\Json::encode(
array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1, 2, 3, 4, 5, 6)
)
);
$response = $this->getResponse();
$response->setContent($json);
$response->getHeaders()->addHeaders(array(
'Content-Type' => 'application/json',
));
return $this->response;
}
As usual framework developer mess thing about AJAX following the rule why simple if might be complex Here is simple solution
in controller script
public function checkloginAction()
{
// some hosts need to this some not
//header ("Content-type: application/json"); // this work
// prepare json aray ....
$arr = $array("some" => .....);
echo json_encode($arr); // this works
exit;
}
This works in ZF1 and ZF2 as well
No need of view scrpt at all
If you use advise of ZF2 creator
use Zend\View\Model\JsonModel;
....
$result = new JsonModel($arr);
return $result;
AJAX got null as response at least in zf 2.0.0
I'm trying to create a form that change the validation of a field based on the select option from the html form field.
Ex: if user select a option 1 from drop down field "options", I want the field "metric" to validate as sfValidatorInteger. If user select option 2 from field "options", I want the field "metric" to validate as sfValidatorEmail, etc.
So inside the public function configure() { I have the switch statement to capture the value of "options", and create the validator based on that value returned from the "options".
1.) How do I capture the value of "options" ? I've tried:
$this->getObject()->options
$this->getTaintedValues()
The only thing that's currently working for me is but it's not really MVC:
$params = sfcontext::getInstance()->getRequest()->getParameter('options');
2.) Once I've captured that information, how can I assign the value of "metric" to a different field? ("metric" is not a real column in db). So I need to assign the value of "metric" to different field such as "email", "age" ... Currently I'm handling this at the post validator like this, just wondering if I can assign value within the configure():
$this->validatorSchema->setPostValidator(new sfValidatorCallback(array('callback' => array($this, 'checkMetric'))));
public function checkMetric($validator, $values) {
}
Thanks!
You want to use a post validator. Try doing something like this in your form:
public function configure()
{
$choices = array('email', 'integer');
$this->setWidget('option', new sfWidgetFormChoice(array('choices' => $choices))); //option determines how field "dynamic_validation" is validated
$this->setValidator('option', new sfValidatorChoice(array('choices' => array_keys($choices)));
$this->setValidator('dynamic_validation', new sfValidatorPass()); //we're doing validation in the post validator
$this->mergePostValidator(new sfValidatorCallback(array(
'callback' => array($this, 'postValidatorCallback')
)));
}
public function postValidatorCallback($validator, $values, $arguments)
{
if ($values['option'] == 'email')
{
$validator = new sfValidatorEmail();
}
else //we know it's one of email or integer at this point because it was already validated
{
$validator = new sfValidatorInteger();
}
$values['dynamic_validation'] = $validator->clean($values['dynamic_validation']); //clean will throw exception if not valid
return $values;
}
1) In a post validator, values can be accessed by using the $values parameter. Just use $values['options'] and it should be fine... or did you want to access this values from another part of you code? $this->getObject()->widgetSchema['options'] should work too I think, once your form is bound to an object.
2) The configure() method is called at the end of the form constructor, so values are not bound nor accessible yet, unless you are initializing your form with an object from the db (which does not require any validation). But if you want to initialize your form from $_POST, a post validator is definitely the way to go IMHO.
I got the validation error to appear alongside the field by throwing a sfValidatorErrorSchema instead of a sfValidatorError.
$values['dynamic_validation'] = $validator->clean($values['dynamic_validation']);
…becomes…
try
{
$values['dynamic_validation'] = $validator->clean($values['dynamic_validation']);
}
catch(sfValidatorError $e)
{
$this->getErrorSchema()->addError($e, 'dynamic_validation');
throw $this->getErrorSchema();
}
Not sure if this is the best way to get this result, but it seems to be working for me at the moment.