Binding text box to telerik upload control MVC3 - asp.net-mvc-3

I want my textbox to display the name of file selected by telerik upload control. Please find the code snippet below.
<td>
#Html.TextBox(txtBox, null, new { style = string.Format("width:200px") })
</td>
<td style="padding-top: 1%; padding-left: 8%">
#(Html.Telerik().Upload().Name(BrowseButton)
//.HtmlAttributes(new { #class = "myCustomClass" }).Multiple(false))
Currently the textbox is displaying null.

The Telerik control should allow you to show the file name. Your extra textbox seems redundant.
Read the telerik documentation and specifically the html and css section. It says the following:
During and after uploading, a file list is displayed, which shows the progress and status of each uploaded file. Its HTML output is the following:
<ul class="t-upload-files t-reset">
<li class="t-file">
<span class="t-icon t-success">uploaded</span>
<span class="t-filename">some-uploaded-file.jpg</span>
<button class="t-button t-button-icontext t-upload-action" type="button">
<span class="t-icon t-delete"></span>Remove</button>
</li>
<li class="t-file">
<span class="t-icon t-fail">failed</span>
<span class="t-filename">some-failed-file.jpg
<span class="t-progress">
<span style="width: 75%;" class="t-progress-status">
</span></span>
</span>
<button class="t-button t-button-icontext t-upload-action" type="button">
<span class="t-icon t-retry"></span>Retry</button>
</li>
</ul>
If you want to update a textbox of your own, simply use their client api by adding this when creating telerik control
#(Html.Telerik().Upload().Name(BrowseButton)
.ClientEvents(events => events.OnSelect("onSelect"))
and in your javascript
function onSelect(e) {
// Array with information about the uploaded files
$('#yourTextboxId').val(e.files[0].name);
}
Again all the details are in the documentation.

Related

alpine js, x-model binds to wrong value when switching tabs

running into an issue with alpine js.
First of all I have a master component that allows the user to switch between two tabs
#props(['pages', 'blogs'])
<div x-data="init()" class="overview row mb30">
<div class="pageContent__content__languages disFlex mb20 bBottom">
<span
#click.prevent='tab = "pages"'
:class='{ "active": tab === "pages" }'
class="pageContent__content__languages__item disFlex aiCenter pt10 pb10 pr10 pl10 mr10 pointer">
Pagina's
</span>
<span
#click.prevent='tab = "blogs"'
:class='{ "active": tab === "blogs" }'
class="pageContent__content__languages__item disFlex aiCenter pt10 pb10 pr10 pl10 bRadius mr10 pointer">
Blogs
</span>
</div>
<div x-show="tab === 'pages'">
<x-form.edit.navigation.pages :pages="$pages" />
</div>
<div x-show="tab === 'blogs'">
<x-form.edit.navigation.blogs :blogs="$blogs" />
</div>
<button type="button" wire:click="navigationAddToMenu" class="btn blue w100 mt10">
Toevoegen aan menu
</button>
</div>
#push('scripts')
#once
<script type='text/javascript'>
function init() {
return {
selected: #entangle('selected'),
tab: 'pages',
};
}
</script>
#endonce
#endpush
These tabs either display pages or blogs depending on which tab is clicked.
Inside of these blade components is just a foreach loop to display the items,
#props(['pages'])
<div style="grid-area: unset" class="pageContent__settings bRadius--lrg disFlex fdCol">
<table class="overview__wrapper">
<tbody class="bRadius--lrg">
#foreach($pages as $page)
<tr class="overview__row bBottom">
<td class="overview__row__checkbox">
<input x-model='selected' value='{{ $page->id }}' type="checkbox"
id="col-row-{{$loop->index}}">
<label for="col-row-{{$loop->index}}"></label>
</td>
<td class="overview__row__name lh1">
{{ $page->page_name }}
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
The blog blade component is nearly identical.
Now the user is able to check a checkbox to add items to their menu, this is binded using the #entangle directive and the x-model on the checkbox.
So far when the user is on the default tab pages and they select a page the correct ID is retrieved from the checkbox, BUT when the user switches tab to the blogs display, and clicks a checkbox the value is retrieved from the pages tab.
e.g.
1 page and 1 blog, page has id of 1 blog has id of 2. User is on the pages tab and clicks on the checkbox the correct value of 1 is now added to the selected array, user switches tabs to blogs and clicks the checkbox the expected behavior would be to have the id of 2 added to the selected array, but it still adds 1.
Inspecting the HTML and the loops do add unique ids to each of their items.
Fixed it, need to make my ids on the input more unique, instead of doing
<input x-model='selected' value='{{ $blog->id }}' type="checkbox"
id="col-row-{{$loop->index}}">
<label for="col-row-{{$loop->index}}"></label>
I added a extra identifier
<input x-model='selected' value='{{ $blog->id }}' type="checkbox"
id="col-row-blogs-{{$loop->index}}">
<label for="col-row-blogs-{{$loop->index}}"></label>
and pages for the pages.
This fixed the issue

Views and downloads count - Update database on view with lightbox and download

I've made a site with laravel and have a page where there are pictures that can be seen in hi-resolution via fancybox or downloaded. In the database i have counters for each action. and I do already have GET routes set up for the counting since they are used in other situations too.
for example: www.mysiste.com/somecode/someothercode/image/viewed
the simplified structure of each image is this.. This is called inside a for each loop.. i removed all styling and classes for better reading...
<div >
<div class="card" style="background-color: lightgray">
<div >
<a data-fancybox="gallery" href="/images/......../{{$photo->filename}}">
<img class="card-img" src="/images/......../thumb/thumb_{{$photo->filename}}">
</a>
</div>
<div class="card-footer">
<div>
<div>
<a download="{{$photo->filename}}" href="/images/......../{{$photo->filename}}">
<span>Download (Hi-Res)</span>
</a>
</div>
<div>
<a download="social_{{$photo->filename}}" href="/images/......../social_{{$photo->filename}}">
<span>Download (Social-Res)</span>
</a>
</div>
</div>
</div>
</div>
</div>
I would need that when they hit the download button it calls a certain URL in the background for upcounting.. (most important)
If possible I would like to hit another URL when the images are viewed fullscreen through fancybox.
how can this be done?
You can do something in the lines of:
<a data-fancybox="gallery" href="{{ route('photo.fancybox', ['photo' => $photo])}}">
<img class="card-img" src="/images/......../thumb/thumb_{{$photo->filename}}">
</a>
...
<a href="{{ route('photo.download', ['photo' => $photo])}}">
<span>Download (Hi-Res)</span>
</a>
PhotoController
public function download(Photo $photo){
$photo->downloadCount->increment();
return redirect('/images/......../'. $photo->filename);
}
public function fancybox(Photo $photo){
$photo->fancyboxCount->increment();
return redirect('/images/......../social_'. $photo->filename);
}
And make sure to register your new routes accordingly:
Route::get('photo/download', 'PhotoController#download')->name('photo.download');
Route::get('photo/fancybox', 'PhotoController#fancybox')->name('photo.fancybox');

Dropzone opens file chooser twice

I have set up dropzone with a clickable element. Clicking the button causes dropzone to open the file chooser twice, instead of just once, the second coming immediately after the first file has been chosen.
The init code is:
Dropzone.autoDiscover = false;
$(document).ready(function(){
// Remove the template from the document.
var previewNode = document.querySelector("#template");
previewNode.id = "";
var previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);
$("div#photo").dropzone({
url: "/blackhole/",
thumbnailWidth: 240,
thumbnailHeight: 240,
parallelUploads: 1,
maxFiles:1,
maxFilesize: 5,
uploadMultiple: false,
previewTemplate: previewTemplate,
autoProcessQueue: true,
previewsContainer: "#photoPreview",
clickable: ".fileinput-button",
init: function() {
this.on("maxfilesexceeded", function(file) {
this.removeAllFiles();
this.addFile(file);
});
}
});
And the page elements are:
<div class="table table-striped" class="files">
<div id="photo">
<div id="actions" class="row">
<div class="col-lg-7">
<button type="button" class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Choose file...</span>
</button>
</div>
</div>
</div>
<div class="files dropzone-previews" id="photoPreview">
<div id="template" class="file-row">
<div>
<span class="preview"><img data-dz-thumbnail /></span>
</div>
<div>
<p class="name" data-dz-name></p>
<strong class="error text-danger" data-dz-errormessage></strong>
</div>
<div>
<p class="size" data-dz-size></p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress></div>
</div>
</div>
<div>
<button data-dz-remove type="button" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
</div>
</div>
</div>
</div>
</div>
Strangely, even though I have added code to replace the any existing file with a later one (so only one file can be uploaded), the second file chooser dialog lets me add a second file.
Its like dropzone has been initialized twice, but I checked that it is only initialized once, and also added the autoDiscover = false option for good measure.
Can anyone spot my mistake?
The problem seems to be in how we initialized dropzone:
$("div#photo").dropzone({
...
}
Doing it the non-jquery way solved the problem:
var myDropZone = new Dropzone("#photo",{
...
}
This was on dropzone 3.11.1.
An issue has been created on github/dropzone:
https://github.com/enyo/dropzone/issues/771
This happens for me when more than one dropzone exists on the page with the same class for a browse trigger, it seems that dropzone attaches the event to any element on the page and not just within its own container
In the issue opened for this, maliayas said:
This bug happens when your clickable element is already an
input[type=file]. Dropzone injects another one and now you have two.
Either dropzone should handle this case or documentation should
mention not to use an input[type=file] for the clickable element.
Changing my dropzone element to something other than an input[type=file] fixed the issue for me.
Attach dropzone to the parent, not the input.
In Chrome if you inspect and look at the eventListeners. You will see that once you attach dropzone to your input, you have an additional click eventListener.
Say you have a list of uploads for documents with a child input element.
<li class="upload drag-and-drop">
<input type="file"/>
</li>
Code:
$('input').dropzone();
Will attach an event listener to an already clickable element. So you have 2 event listeners. One from the browser. One from dropzone. Hence 2 dialogs...
If you attach it to the parent:
$('li.upload').dropzone();
You'll now had the listener at the parent. This allows the bubble up behavior to hit the correct element when you drag and drop and not inadvertently effect the input.

Bootstrap menu collapse in ajax site. How can i close menu on every click?

my website uses Ajax and i want to close the Bootstrap's collapsed menu every time a user click click on every menu item, like this code. But this code doesn't work!! Damn!
$('.menu-item').click(function() {
$('.collapse').collapse('hide');
});
How can I fix it?
(The code of menu is a simply bootstrap 3.0.0):
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
And the code of menu:
<div class="col-md-6 downmy">
<div class="navbar-collapse in" style="height: auto;">
<div class="menuTop"><ul id="menu-primary" class="nav nav-pills"><li id="menu-item-605" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-605">Home</li>
<li id="menu-item-314" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-314">My Posts</li>
<li id="menu-item-315" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-315">Guestbook</li>
</ul>
</div>
</div>
</div>
When an element with class '.collapse' collapse or become visible the '.collapse' class will be replace by the .in class. So you will have to apply your hide on the .in class too.
$('.menu-item').click(function() {
$('.in').collapse('hide');
});
Your menu items contain an anchor, when click this a new page will open... so i don't understand your question. To prevent this add an event.preventDefault (http://api.jquery.com/event.preventDefault/) to your code:
$('.menu-item').click(function(event) {
event.preventDefault();
$('.in').collapse('hide');
});
The following query worked fine for me :
//The ":not('.dropdown-toggle')" is for the drop down menu (like a language menu) because
// I didn't want my navigation to close when clicking sub menu
$(".nav li a:not('.dropdown-toggle')").on('click',function(){
$('.navbar-collapse.in').collapse('hide');
});
You can add it to your page or in the $(document).ready(function(){/*...*/}); method

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?
I don't get the expected results when using the following:
HTML
<div id="itemsView"
data-role="view"
data-model="vm">
<ul data-role="listview" data-bind="source: items"
data-template="itemsTemplate">
</ul>
<script id="itemsTemplate" type="text/x-kendo-template">
<li>
#=Name#
</li>
</script>
<input type="text" data-bind="value: newValue" />
<button data-role="button" data-bind="click: update">update</button>
</div>​
JavaScript
var vm = kendo.observable({
items: [{
Name: "Item1"}],
newValue: '',
update: function(e) {
var item = this.get("items")[0];
item.set("Name", this.get("newValue"));
//adding the follwoing line makes it work as expected
kendo.bind($('#itemsView'), vm);
}
});
kendoApp = new kendo.mobile.Application(document.body, {
transition: "slide"});​
I expect the listview to reflect the change to the Name property of that item. Instead, a new item is added to the listview. Examining the array reveals that there is no additional item, and that the change was made. (re)Binding the view to the view-model updates the list to reflect the change. Re-Binding after a change like this doesn't seem to make any sense.
Here is the jsfiddle:
http://jsfiddle.net/5aCYp/2/
Not sure if I understand your question properly: but this is how I did something similar with Kendo Web UI, I expect mobile is not so different from Web UI from API perspective.
$element.kendoListView({
dataSource: list,
template: idt,
editTemplate: iet,
autoBind: true
});
The way I bind the listview is different, but I guess you can get similar results with your method as well.
I pass two templates to the list view, one for displaying and one for editing.
Display template contains a button (or any element) with css class k-edit to which kendo will automatically bind the listview edit action.
display template:
<div class="item">
# if (city) { #
#: city #<br />
# } #
# if (postCode) { #
#: postCode #<br />
# } #
<div class="btn">
<span class="k-icon k-edit"></span>Edit
<span class="k-icon k-delete"></span>Delete
</div>
</div>
Edit template
<div class="item editable">
<div>City</div>
<div>
<input type="text" data-bind="value: city" name="city" required="required" validationmessage="*" />
<span data-for="city" class="k-invalid-msg"></span>
</div>
<div>Post Code</div>
<div>
<input type="text" data-bind="value: postCode" name="postCode" required="required" validationmessage="*" />
<span data-for="postCode" class="k-invalid-msg"></span>
</div>
<div class="btn">
<span class="k-icon k-update"></span>Save
<span class="k-icon k-cancel"></span>Cancel
</div>
</div>
Clicking that element will put the current element on edit mode using the editTemplate.
Then on the editTemplate there is another button with k-update class, again to which kendo will automatically bind and call the save method on the data source.
Hopefully this will give you more ideas on how to solve your issue.
The problem was caused by the <li> in the template. The widget already supplies the <li> so the additional <li> messes up the rendering. This question was answered by Petyo in the kendo ui forums

Resources