This is a very simple question.
I have a Html.helper:
#Html.DisplayFor(modelItem => item.Text)
How to I cut down the string from item.Text to a specific length? I wish you could do a SubString or something directly on the item.Text.
If youre wondering why I want this, its because the strings are very long, and I only want to show a bit of it in like the index view etc.
I needed the same thing and solved the case with the following lines.
<td>
#{
string Explanation = item.Explanation;
if (Explanation.Length > 10)
{
Explanation = Explanation.Substring(0, 10);
}
}
#Explanation
</td>
If your string is always larger than 10, you can rule out:
if (Explanation.Length > 10)
{
Explanation = Explanation.Substring(0, 10);
}
And directly write:
string Explanation = item.Explanation.Substring(0, 10);
Also I recommend adding .. for strings larger than the limit you give.
There are 3 possibilities that could be considered:
Strip the text in your mapping layer before sending it to the view (when converting your domain model to a view model)
Write a custom HTML helper
Write a custom display template for the given type and then 3 possibilities to indicate the correct display template: 1) rely on conventions (nothing to do in this case, the template will be automatically picked) 2) decorate your view model property with the UIHint attribute 3) pass the template name as second argument to the DisplayFor helper.
You could just add a property onto your view model that does the truncation of the string and display that instead:
// View model
public string TextShort { get { return Text.Substring(0, 10); } }
// View
#Html.DisplayFor(modelItem => item.TextShort)
Change
#Html.DisplayFor(modelItem => item.Text)
to
#Html.Display(item.Text.Length > 10 ? item.Text.Substring(0,10) : item.Text)
Edited : New Answer
what about
#{
modelItem.ShortText= model.Text.Substring(0, ....);
}
#Html.DisplayFor(modelItem => item.ShortText)
The prototype for DisplayFor is :
public static MvcHtmlString DisplayFor<TModel, TValue>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression
)
And the modelItem is a dynamic I think, so it should be possible to add anew property to the view model.
Related
In my view I have
#model Models.ViewModel.MyViewModel
I can get the values displayed with the Html.DisplayNameFor(model => model.my_id) method. This works fine.
But I cannot get the value of a field in the model by doing anything like
int id = model.my_id;
Every time I use "model," Visual Studio cannot find a reference to it. It does for the Html Helpers, but not when model is not in an Extension method like in the HtmlHelper (I thought it was an Extension Method).
I have tried many variations and various solutions I found on SO. I am missing something fundamental, but I cannot find the answer of how to get the reference to model and its values.
It is also causing this to fail,
#Html.ActionLink("Edit", "Edit", new { id = model.my_id })
What am I doing wrong?
Use Model with a capital M.
#{
int id = Model.my_id;
}
#Html.ActionLink("Edit", "Edit", new { id = Model.my_id })
in my db structure
service_request type enum('towel','tissue','napkin')
then have a model
* #property string $service_request
then in my view
<?= $form->field($model, 'service_request')->checkBoxList([ 'towel' => 'Towel', 'tissue' => 'Tissue', 'napkin' => 'Napkin']) ?>
then when i choose towel, tissue and napkin then submit the form, it's have an error said
Service Request must be String
please help me
Thank You
Like Joji Thomas said, checkBoxList prodices an array.
You need to change your database structure so that it supports 1-to-many relations (each $model can have multiple service_requests) if you want to save this. Unfortunately Yii is not very good at this sort of thing out of the box so you have to do a bunch of things yourself.
First you need to create a ServiceRequest ActiveRecord.
Then your $model needs to have a relation like:
public function getServiceRequests() {
return $this->hasMany(ServiceRequest::className(), ['model_id' => 'id'];
}
Then in your controller (model create action) you will need to do something like this:
foreach (Yii::$app->request->post('ServiceRequest',[]) as $data) {
$item = new ServiceRequest($data);
$model->link('serviceRequests', $item);
}
If you wanna update the checkboxes too then you need to do something similar in your model update action as well.
Please change checkBoxList to radioList, because when selecting multiple values service_request becomes an array. Enum type can handle only string values.
First change your filed datatype from enum to varchar. enum only takes a single string value.
Secondly you need to implode service_request array to string for save to db.
Use bellow code before the model save function :
$model->service_request = implode("," , $model->service_request);
$model->save();
I would like to generate the following HTML with Mithril's m:
<p>I am a <code>person</code></p>.
I'm currently using m.trust for this:
m.trust("<p>I am a <code>person</code></p>").
But I don't like the HTML string. Is there a better way to do this?
Yes, use m function to do this:
m('p', [
'I am a ',
m('code', 'person')
])
See a whole component here: https://jsfiddle.net/rtkhanas/02adbhkt/
Where the html string come from?
If you are writing your view, then use m('p', ...) instead of m.trust
For example, if only the "person" value is dynamic, you should have something like:
window.WhoAmI = {}
WhoAmI.controller = function(attr) {
var ctrl = this
ctrl.gender = m.prop(attr.gender)
}
WhoAmI.view = function(ctrl) {
return m('p', [
'I am a ',
m('code',
ctrl.gender()
)
])
}
If you get the whole html string from a request, then it's probably a bad thing, and you should try to rewrite your API (if possible) to send only the dynamic value to the client.
You should have something like this:
m.module(document.body, {
view: function() {
return m('p', [
'I am a ',
m('code', 'person')
]);
}
})
I need to use article name on the url on Yii2 which is like http://example.com/article?id=1, just replace id=1 to article_name, like http://example.com/article/article_name or is it.
This is my controller code-
$model = Articles::find()->orderBy(['id' => SORT_DESC])->one();
View-
<?= Html::a('<b>Read more ...</b>', ['article-details','id' => $model->id], ['target'=>'_blank']) ?>
Thanks advance
You may use yii2 sluggable behavior Refer this.
There are few steps.
You must add the following urlManager rule :
'article/<slug>' => 'article/view',
You should build url in your view files like this :
\yii\helpers\Url::to(['article/view', 'slug'=>$model->title])
or
\yii\helpers\Url::to(['article/'.$model->title]);
And in your action
public function actionArticle($slug){
$model = Articles::find()->where(["title"=>$slug])->orderBy(['id' => SORT_DESC])->one();
//and other code
}
Also your article titles must be valid for url.You can do it easly by trimming whitespaces and so on But also you can add url some identification propery. or add column stored unique slugs for every article
You have two way
one change the related action in the controller changing id with name in the related function declaration
or declare a new action with the name as parameter
public function findModelName($article_name)
{
$model = Article::findOne(['name'=> $article_name]);
........ your related code
}
you can find the model by name this way
Article::findOne(['name'=> $article_name]);
I am outputting an address that I would like to comma separate.
If I don't include any html before outputting the address it is shown correctly without any additional spaces.
Example:
97 Glen Road, Holywood, BT18 0LE
Currently Getting:
97 Glen Road , Holywood , BT18 0LE
My code is:
<p class="no-margin-top">#Html.DisplayFor(modelItem => item.Address1)
#if(!string.IsNullOrEmpty(item.Address2)){
#:, #Html.DisplayFor(modelItem => item.Address2)
}
#if(!string.IsNullOrEmpty(item.Address3)){
#:, #Html.DisplayFor(modelItem => item.Address3)
}
#if(!string.IsNullOrEmpty(item.Town)){
#:, #Html.DisplayFor(modelItem => item.Town)
}
#if(!string.IsNullOrEmpty(item.County)){
#(", ")#("Co. ")#Html.DisplayFor(modelItem => item.County)
}
#if(!string.IsNullOrEmpty(item.Postcode)){
#(", ")#Html.DisplayFor(modelItem => item.Postcode)
}
#if(!string.IsNullOrEmpty(item.Country)){
#(", ")#Html.DisplayFor(modelItem => item.Country)
}
I have tried outputting the comma differently as shown above but still getting the same result.
I have also tried removing all spaces from the code as well as using #Html.Raw.
Would appreciate it if anyone has a fix for this or could suggest a better way of doing it.
UPDATE
Due to changes within the Framework Darin's solution will now produce errors.
You will need to ensure you are using System.Linq
Then amended Darin's code as follows:
public string FormattedAddress
{
get
{
var values = new[] { Address1, Address2, Address3, Town, Postcode, "Co. " + County }.Where(x => !string.IsNullOrEmpty(x));
return string.Join(", ", values);
}
}
WOW, this looks like a terrible mess you've ended up in your view. I would recommend you to use a view model and add the following property to your view model that will take care of properly formatting the address:
public string FormattedAddress
{
get
{
var values = new[] { Address1, Address2, Address3, Town, Postcode, "Co. " + County }
.Where(!string.IsNullOrEmpty);
return string.Join(", ", values);
}
}
and then in your view replace the mess with:
<p class="no-margin-top">
#Html.DisplayFor(modelItem => item.FormattedAddress)
</p>
and if now you tell me that you have violated all good practices and are not using view models, but are passing directly your domain entities to the view, well, other than telling you that this is wrong you could somehow hack it in the view:
<p class="no-margin-top">
#{
var values = new[] { item.Address1, item.Address2, item.Address3, item.Town, item.Postcode, "Co. " + item.County }
.Where(!string.IsNullOrEmpty);
var formattedAddress = string.Join(", ", values);
}
#formattedAddress
</p>
But honestly go use a view model.
Try forcing the comma plus space to be text using a razor text markup. It may be a razor interpretation problem.
{<text>, </text>#Html.DisplayFor(modelItem => item.Address2)}
Good luck