Telerik MVC problem with window and Razor view engine - asp.net-mvc-3

I'm trying to upgrade my project to use Razor.
I have used the Telerik conversion tool https://github.com/telerik/razor-converter
to convert my views to Razor but I am getting errors related to the Telerik Window control.
Here is an example of the markup for the window control:
#Html.Telerik().Window()
.Name("ClientWindow")
.Content(#<text>
<div id="Div1">
<div class="bgTop">
<label for="drpFilter">
Filter:</label>
#Html.DropDownListFor(x => x.ClientLookupViewModel.SelectedFilter, Model.ClientLookupViewModel.FilterBy, new { id = "drpClientFilter" })
<label>
By:</label>
#Html.TextBoxFor(x => x.ClientLookupViewModel.FilterValue, new { id = "filterValue" })
<button type="button" value=" " class="t-icon t-refresh refreshButton" title="Refresh Client & Matter"
onclick="refreshClientClicked()">
</button>
#Html.ValidationMessageFor(x => x.ClientLookupViewModel.FilterValue)
</div>
<iframe id="frameClientLookup" src="#Url.Action("ClientIndex","Lookup")" style="border: 0px;
height: 404px; width: 100%; margin: 0px; padding: 0px;"></iframe>
<div class="bgBottom">
<input style="float: right; margin-top: 5px" type="button" value="OK" id="Button1" onclick="btnClientOkayClicked()" /></div>
</div>
</text>)
.Modal(true)
.Width(800)
.Height(473)
.Title("Client Lookup")
.Buttons(buttons => buttons.Refresh().Maximize().Close())
.Visible(false)
.HtmlAttributes(new { id = "ClientWindow" })
.Render();
This gives the following error
Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: "<" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid.
Source Error:
Line 41: #Html.Telerik().Window()
Line 42: .Name("ClientWindow")
Line 43: .Content(#<text>
Line 44:
Line 45: <div id="Div1">
-----------------------
Does anyone know what the problem is here ?
Thanks

You should change your code like this:
OLD:
#Html.Telerik().Window()
/* rest is omitted for brevity */
.Render();
NEW:
# {
Html.Telerik().Window()
/* rest is omitted for brevity */
.Render();
}

Since you have whitespace and newlines in that code nugget, you need to wrap the whole thing in parentheses to force Razor to continue parsing it past the newline.

Related

How to solve unexpected number of root elements issue in alpine js?

I am working on functionality in alpine js where I need to add a radio button inside the template tag.
Here is what I am doing.
<div class="customRadioStyle">
<template x-for="name in record.names">
<input type="radio" :value="name.value" :id="name.id">
<label :for="name.id" x-text="name.value"></label>
</template>
</div>
But this code gives me the following error.
Alpine: <template> tag with [x-for] encountered with an unexpected number of root elements. Make sure <template> has a single root element.
Is there any solution for this?
I check this link too but still not able to find a solution for this.
https://github.com/alpinejs/alpine/issues/539
Any help would be appreciated.
Just do what the error says and make sure there's a single element inside the <template>. In you case, you can just add the <input> inside the <label> or wrap them both with a <div>:
window.MyComponent = () => ({
names: [{
id: 'name1',
value: 'Name 1',
}, {
id: 'name2',
value: 'Name 2',
}, {
id: 'name3',
value: 'Name 3',
}],
});
body {
font-family: monospace;
}
label {
display: flex;
align-items: center;
padding: 4px 0;
}
input {
margin: 0 8px 0 0;
}
<div x-data="MyComponent()">
<template x-for="name in names">
<label :for="name.id">
<input type="radio" :value="name.value" :id="name.id" name="radioGroup">
<span x-text="name.value"></span>
</label>
</template>
</div>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js"></script>
Note that in the event handler I'm still calling it e, but in the HTML I've used download($event) instead of download(e).

How to display only single validation error at a time

I have this code to which displaying errors on my form
<input [ngFormControl]="form1.controls['thing']" type="text" id="thing" #thing="ngForm">
<div *ngIf='thing.dirty && !thing.valid'>
<div class="err" *ngIf='thing.errors.required'>
Thing is required.
</div >
<div class="err" *ngIf='thing.errors.invalid'>
Thing is invalid.
</div >
</div>
But in case of thing has two errors in it the two error show up.
Lets say if my input has 5 validators so 5 divs will show up which is not nice.
How to display just one error div at a time?
You could create a custom pipe to get the first element of the errors object of the validator:
#Pipe({
name: 'first'
})
export class FirstKeyPipe {
transform(obj) {
var keys = Object.keys(obj);
if (keys && keys.length>0) {
return keys[0];
}
return null;
}
}
This way you would be able to display only one error:
#Component({
selector: 'my-app',
template: `
<form>
<input [ngFormControl]="form.controls.input1">
<div *ngIf="form.controls.input1.errors">
<div *ngIf="(form.controls.input1.errors | first)==='required'">
Required
</div>
<div *ngIf="(form.controls.input1.errors | first)==='custom'">
Custom
</div>
</div>
</form>
`,
pipes: [ FirstKeyPipe ]
})
export class MyFormComponent {
constructor(private fb:FormBuilder) {
this.form = fb.group({
input1: ['', Validators.compose([Validators.required, customValidator])]
});
}
}
See this plunkr: https://plnkr.co/edit/c0CqOGuzvFHHh5K4XNnA?p=preview.
Note: agreed with Günter to create a usable component ;-) See this article for more details:
http://restlet.com/blog/2016/02/17/implementing-angular2-forms-beyond-basics-part-2/
If you have consistent markup for your error message blocks, then you can use css to display only the first message and hide the rest:
css
.message-block .error-message {
// Hidden by default
display: none;
}
.message-block .error-message:first-child {
display: block;
}
markup
<div class="message-block">
<span class="error-message" *ngIf="myForm.get('email').hasError('required')">
Email is required (first-child of message block is displayed)
</span>
<span class="error-message" *ngIf="myForm.get('email').hasError('email')">
Invalid email format (error message hidden by default)
</span>
</div>
<input [ngFormControl]="form1.controls['thing']" type="text" id="thing" #thing="ngForm">
<div *ngIf='thing.dirty && !thing.valid'>
<div class="err" *ngIf='thing.errors.required'>
Thing is required.
</div >
<div class="err" *ngIf='!thing.errors.required && thing.errors.ivalid'>
Thing is invalid.
</div >
</div>
You could create a reusable component for showing errors so you don't need to repeat this code again and again.
This works and you don't have to hardcode the validations in you template like #Joes answer above.
Template:
<input id="password" placeholder="Password" type="password" formControlName="password" [(ngModel)]="password" [ngClass]="{'invalid-input': !formUserDetails.get('password').valid && formUserDetails.get('password').touched}">
<div class="validation-container">
<ng-container *ngFor="let validation of userValidationMessages.password">
<div class="invalid-message" *ngIf="formUserDetails.get('password').hasError(validation.type) && formUserDetails.get('password').touched">
{{validation.message}}
</div>
</ng-container>
</div>
CSS:
.validation-container div {
display: none;
}
.validation-container div:first-child {
display: block;
}
Angular2 behind the scene checks the status of the control and reacts accordingly. So if you don't want to have more validation at a time, you can logically play with AND(&&) or/and OR(||) or/and NOT(!) operators.
You can create a Custom Pipe that checks first error equals with specified error:
CUSTOM PIPE
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'equals'
})
export class Equals implements PipeTransform {
transform(errors: any, error: any, args?: any): any {
if (!errors)
return false;
const array = Object.keys(errors);
if (array && array.length > 0)
return errors[array[0]] === error;
return false;
}
}
You can have lots of error div but just one error will be shown:
// input is form.controls.input1
<div *ngIf="input.errors | equals:input.errors.required">Required</div>
<div *ngIf="input.errors | equals:input.errors.maxlength">MaxLength</div>
<div *ngIf="input.errors | equals:input.errors.pattern">Pattern</div>

get width of a div which was generated by javascript on runtime

I have few columns which was generated by dhtmlx's javascript. The column was generated on run time which means that if I tried to view the source code of the page using the Chrome's View Page Source, I won't be able to see the generated code. But I can see the generated code by right clicking on the element and select 'Inspect Element'. So here's a part of the generated code that I copy pasted from 'Inspect Element':
<div id="scheduler_here" class="dhx_cal_container dhx_scheduler_grid" style="width:100%;height:100%;">
<div class="dhx_cal_header" style="width: 1148px; height: 20px; left: -1px; top: 60px;">
<div class="dhx_grid_line">
<div style="width:169px;">Start Date</div>
<div style="width:169px;">Time</div>
<div style="width:169px;">Event</div>
<div style="width:169px;">Location</div>
<div style="width:169px;">Stakeholders</div>
<div style="width:169px;">Type</div>
</div>
</div>
<div class="dhx_cal_data" style="width: 1148px; height: 506px; left: 0px; top: 81px; overflow-y: auto;">
<div>
<div class="dhx_grid_v_border" style="left:184px" id="imincol0"></div>
<div class="dhx_grid_v_border" style="left:370px" id="imincol1"></div>
<div class="dhx_grid_v_border" style="left:556px" id="imincol2"></div>
<div class="dhx_grid_v_border" style="left:742px" id="imincol3"></div>
<div class="dhx_grid_v_border" style="left:928px" id="imincol4"></div>
</div>
<div class="dhx_grid_area"><table></table></div>
</div>
</div>
I'm trying to get the column width of imincol0, imincol1, imincol2 and so on which you can see at the last part of the code. I have tried few methods to get the width of the columns with these ids but to no avail. I'll always get null.
If you use jquery you could do this:
var x = $('#imincol0').width();
If you're using pure js you could try this:
var x = document.getElementById('imincol0').offsetWidth;

jquery ajax form submit plugin not posting file input

I've got this form:
<form id="imageinputpopup" class=suggestionsubmit style="display: none">
<span>Add a thing!</span><br/>
<label>url: </label><input name="imageurl" type="url"><br/>
<label>file: </label><input name="imagefile" type="file"><br/>
<input type='hidden' name='schoolid' class="schoolid">
<input type="submit" value="Submit">
</form>
And this document.ready:
<script type="text/javascript">
$(document).ready(function() {
$('.schoolid').val(get_gmap_value('school_id'));
$(".allow-submission").live('click', function(){
if($(this).attr('inputtype')=="colorpicker"){
.....
} else if($(this).attr('inputtype')=="image"){
remove_hidden("#imageinputpopup");
add_fieldname($(this), $("#imageinputpopup"));
$("#imageinputpopup").dialog();
} else if($(this).attr('inputtype')=="text"){
....
} else {
//nothing
}
});
$(".suggestionsubmit").submit(function(){
event.preventDefault();
alert($(this).html());
$(this).ajaxSubmit({
url: '/save-school-suggestion/',
type: 'post',
success: function(response){
response = jQuery.parseJSON(response);
// Check for login redirect.
// if ( response.requireLogin ) {
// alert('Sign up or log in to save your answer');
// } else {
$('.suggestionsubmit').dialog('close');
// }
}
});
});
});
function add_fieldname(element, addto){
var elementname = document.createElement('input');
elementname.type = 'hidden';
elementname.name = 'fieldname';
elementname.value = element.attr('fieldname').replace(' ', '_');
$(elementname).addClass('fieldname');
addto.append(elementname);
}
function remove_hidden(element){
$(element+' .fieldname').remove();
}
But the file field isn't showing up server side.
Why?
I found this in the documentation:
Why aren't all my input values posted?
jQuery form serialization aheres closely to the HTML spec. Only successful controls are valid for submission.
But I don't understand why my file control would be invalid.
I have another submission form in a different place on my site that is almost identical and works perfectly...
EDIT: this is the other form that does work (it has some extra stuff in it, but the form tag just has an id, like the problem one, and the input tags are the same).
<form id="photos-submission-form6">
<input type="hidden" name="section" value="photos">
<input type="hidden" name="school" id="photos-submit-school6">
<div style="margin-bottom: .5em">
<p style="position: relative; width:80%; font-size: 14px; display: inline" id="photos-anonymity-header6">Post as: null</p>
<img id="helpicon6" src="/static/img/help-icon.png" style="float: right; cursor: pointer; padding-left:1em;">
<div id="explanation6" style="display: none; padding:1em; background-color:white; border:2px solid gray; position: absolute;z-index:30; right:5px; top:5px">For more posting options, <a id="profilelink6" href="/profile/">fill out your profile</a></div>
</div>
<div id="photos-anonymity-select6" style="margin-bottom: .75em; width:412px" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all"><a class="ui-slider-handle ui-state-default ui-corner-all" href="#" style="left: 100%; "></a></div>
<input type="hidden" id="photos-anonymity-level6" name="anonymity-level" value="username">
<span style="line-height: 40px;">
<label class="photouploadlabel">URL</label><input type="text" name="image-url" style="width: 335px"><br>
<label class="photouploadlabel">File</label><input type="file" name="image-file" style="width: 335px"><br>
<label class="photouploadlabel">Caption</label><input type="text" id="image-caption6" name="image-caption" style="width: 335px; color: rgb(128, 128, 128); ">
</span>
<div style="height: 30px; margin-top: 1em; width: 413px;">
<label id="photos-tagsbutton6" style="margin-right: .5em; cursor: pointer; vertical-align: bottom; float:left; line-height: 1.8em;">Tags</label>
<input id="photos-tagsinput6" style="display: none;" type="text" name="tags">
<button id="send-photos-suggestion6" disabled="" style="float:right; position: relative; bottom: 7px; right: -4px;" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-disabled ui-state-disabled ui-button-text-only" role="button" aria-disabled="true"><span class="ui-button-text">Post</span></button>
</div>
</form>
This is probably not the case but are sure there are no spelling mistake server side? like you would be using $_FILE instead of $_FILES? Could you post the relevant php also?
Also, definitely not an issue but it is recommended to close your input tags, now like this:
<input ... />
Add enctype="multipart/form-data" attribute to your form.
Try to change the type of the input imageurl from url to text:
FROM:
<label>url: </label><input name="imageurl" type="url"><br/>
TO:
<label>url: </label><input name="imageurl" type="text"><br/>
I am not sure, but maybe the jquery plugin fails serializing the form due to invalid type attribute of image_url.
Hey you just forgot to add ---> enctype="multipart/form-data" in the form tag. This will help you out.
I think you have a problem with the binding in javascript not recognising your file.
Try binding your submit trigger event with another live() function
i.e. change
$(".suggestionsubmit").submit(mooFar(e));
to
$(".suggestionsubmit").live('submit', mooFar(e));
...........I was looking in the wrong place in the request for the file.
Server side should have been:
if not s.url_field and 'imagefile' in request.FILES:
s.image_field = request.FILES['imagefile']
instead of
s.image_field = request.POST.get('imagefile', None)
Complete and utter fail on my part.
Make sure the files you're testing aren't outside the max file size, it would be worth setting this in your HTML.
<input type="hidden" name="MAX_FILE_SIZE" value="500" />
Also, testing without the display:none might be worth while until you have the form working; which browser are you testing in?

ajax window doesnt work when tag is deeply nested in the DOM

i am struggeling with a ajax window getting opened in deep nested DOM. I am not that good in jquery so i try to find some help here.
jWindow is supposed to open a new window on click with ajax-content.
For testing i put a Link just under the first DIV. THIS WORKES PERFECT !!!
Then i added some code to generate a TABLE with contains one coloum with a Number which contains the SAME a-tag as the test on top. THIS DOES NOT WORK.
Here is a copy of the DOM(i put horizontal rules around the two a-tags to make it more easy to find them):
<div id="content">
<p>
<a class="get_detail_bill_window" bnr="177" shop="2" href="#">Text Ajax</a>
</p>
<div id="form_selection">
<div class="ui-widget ui-widget-content ui-corner-all" style="padding: 5px; font-size: 1em; width: 1200px;">
<div class="t_fixed_header_main_wrapper ui-widget ui-widget-header ui ui-corner-all">
<div class="t_fixed_header_caption ui-widget-header ui-corner-top">
<div class="t_fixed_header_main_wrapper_child">
<div class="t_fixed_header ui-state-default ui" style="border: medium none; font-weight: normal;">
<div class="headtable ui-state-default" style="margin-right: 15px;">
<div class="body ui-widget-content" style="height: 340px; overflow-y: scroll;">
<div>
<table id="atcs_sort" style="width: 1182px;">
<colgroup>
<tbody>
<tr>
<td class="ui-widget-content">2011-10-16</td>
<td class="numeric ui-widget-content">
<a class="get_detail_bill_window" bnr="341" shop="2" href="#">341</a>
</td>
<td class="numeric ui-widget-content">02:25:08</td>
<td class="numeric ui-widget-content">2011-10-16</td>
If you have a look at these 2 anchors, they are absolute the same. But the one nested in the DOM does not want to work.
Here is the code of the Document ready:
$(".get_detail_bill_window").on({
click: function() {
var shop=$(this).attr('shop');
var bnr=$(this).attr('bnr');
alert("bin im Click - Shop: "+shop+" Billnr: "+bnr);
var a = $.jWindow
({
id: 'detail_bill',
title: 'Details of Bill-Nr.: '+bnr,
minimiseButton: false,
maximiseButton: false,
modal: true,
posx: 450,
posy: 50,
width: 700,
height: 200,
type: 'ajax',
url: 'sge_detail_bill.php?s='+shop+'&bnr='+bnr
}).show();
a.update();
}
});
I tried this to see, if the selector might have a problem:
var pars = $(".get_detail_bill_window");
for( i=0; i<pars.length; i++ ){
alert("Found paragraph: " + pars[i].innerHTML);
}
But i found all(the top sample AND the nested ones) of the a-tags with this class.
So, i am totally lost and desperate. No idea why these nested links are not working.
If somebody have a solution, i would be very greatful.
Many Thanks in advance,
Joe
what is your question put short? rephrase plz. but in case i understood correctly, you want to loop throguh all the elements in your DOM
lets say php made it look like
<.div id='foo'>
<.ul>
<.li><.span id='foo1'><./span><.span id='foo2'><./span><./li>
<.li><./li>
<.li><./li>
<./ul>
<./div>
and to access each of the inner elements do
$('#foo foo1').click(function(){// handler in
$('#foo #foo1').parent().each(function(){// access element, go back to li, loop through all of them
$('#foo2',this).show();// on click of foo1, foo2 will show (as an example)
});
},function(){// handler out
$('#foo #foo1').parent().each(function(){
$('#foo2',this).hide();
});
});
hope this helps somewhat

Resources