I have a table and have a upload picture. I also have a picture that is already displayed. What I want to do is when I upload a new picture it will overwrite the already displayed picture. In my fiddle I have a duck pic and when I upload new pic it display as another image. How can I hide the duck pic when the user upload new pic?
Link in my fiddle: http://jsfiddle.net/DharkRoses/m2qagzzk/6/
sample code:
angular.module('test', []);
angular.module('test').controller('UploadCtrl', function ($scope, $timeout) {
$scope.thumbnail = {
dataUrl: []
};
$scope.fileReaderSupported = window.FileReader != null;
$scope.photoChanged = function (files, index) {
if (files != null) {
var file = files[0];
var index = this.$index;
if ($scope.fileReaderSupported && file.type.indexOf('image') > -1) {
$timeout(function () {
var fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = function (e) {
$timeout(function () {
$scope.thumbnail[index] = {dataUrl: e.target.result};
});
}
Use this code:: demo
<img ng-if="!thumbnail[$index].dataUrl"ng-src="http://s13.postimg.org/w0v662g93/pink_04.png" height="50px" />
AngularJS views support binary operators
condition && true || false
You can use ng-src with conditions:
<img ng-src="{{thumbnail[$index].dataUrl.length !== 0 && thumbnail[$index].dataUrl || 'http://s13.postimg.org/w0v662g93/pink_04.png'}}" height="50px" />
HTML:
<tr ng-repeat="i in [1, 2, 3, 4]">
<td>{{i}}</td>
<td>
<input type="file" name="file" onchange="angular.element(this).scope().photoChanged(this.files)" /> </td>
<td>
<img ng-src="{{thumbnail[$index].dataUrl.length !== 0 && thumbnail[$index].dataUrl || 'http://s13.postimg.org/w0v662g93/pink_04.png'}}" height="50px" />
</td>
</tr>
fiddle
Related
There is a representation in the form of a table. If I click on the row name in the table, a modal window is displayed. Modal window with a form that is quite complex.
To display the modal window I use the following code:
$('#modal-container').on('shown.bs.modal', function (event) {
var button = $(event.relatedTarget); // Button that triggered the modal
var url = button.attr("href");
var modal = $(this);
modal.find('.modal-content').load(url);
});
$.ajaxSetup({ cache: false });
$('#modal-container').on('hidden.bs.modal', function () {
$(this).removeData('modal');
});
There are the following problems:
when repeated calls for some very short time, the contents of the last call are displayed - it is not so important
sometimes new content is not displayed at all, and the modal window contains information from the last call - it's very important
tell me, please, what could be the problem. I do not know much about JS
code where content is downloaded:
<div id="modal-container" class="modal fade hidden-print" #*tabindex="-1" *# role="dialog" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
call from the action method
return PartialView("Details", projectECVM);
I suspect that the js runs faster than the razor generates the page.
Here I am forming a call for the action method:
#foreach (var item in Model.ProjectVM)
{
<tr class="clickableProject" id="#item.Id" title="View BugReports for #item.ProjectName">
<td id="Name">
<a id="details-link" asp-action="Details" asp-controller="Project" asp-route-id="#item.Id" title="View details project #item.ProjectName" data-toggle="modal" data-target="#modal-container">#Html.DisplayFor(it => item.ProjectName)</a>
</td>
<td id="Owner">
<label class="clickableProject">#item.Owner</label>
</td>
<td id="TrelloBoardURL">
<a id="trelloboard-link" href="#item.TrelloBoardURL" title="Go to TrelloBoard" target="_blank"><img src="~/images/trello-logo-blue.png" height="20" /></a>
</td>
<td id="Modification">
<label class="clickableProject">#item.Modification</label>
</td>
<td id="By">
<label class="clickableProject">#item.By</label>
</td>
<td id="DateTime">
<label class="clickableProject">#item.EntryDateTime</label>
</td>
</tr>
}
Clear the content of the dialog box before loading new content:
$(document).ready(function () {
$(function () {
$('#modal-container').on('shown.bs.modal', function (event) {
var button = $(event.relatedTarget); // Button that triggered the modal
var url = button.attr("href");
var modal = $(this);
$(this).empty(); //adding this part before reloading it.
modal.find('.modal-content').load(url);
});
$.ajaxSetup({ cache: false });
$('#modal-container').on('hidden.bs.modal', function () {
//$(this).empty(); //moved from shown
$(this).removeData('modal');
});
if ($('#modal-container').text().trim().length > 0) {
$('#modal-container').dialog('open');
}
else {
}
});
});
I have a textbox on my form:
<input type="text" class="input-group-field" id="draftSearchProducts" name="draftSearchProducts" placeholder="SearchProducts" />
In my controller I have the following:
[HttpGet]
public ActionResult SearchResults(string keywords, int queryLimit = 20, int offset = 0)
{
try
{
ProductSearchResults searchResults = new ProductSearchResults();
ComApiData<GetProductsDataConnector> productData = new ComApiData<GetProductsDataConnector>();
var products = productData.Connector.GetProductBySearch(new ProductRequestParameters()
{
Search = keywords,
LTPMerchantId = merchantId,
QueryLimit = queryLimit,
QueryOffset = offset
});
searchResults.ProductDetails = products.ToList();
return PartialView("_SearchResults", searchResults);
}
catch (Exception ex)
{
throw ex;
}
}
And there is a button on the form:
<a id="draftAddProduct" class="hollow button secondary"><i class="fa fa-plus"></i> Add Product</a>
Since I am new to this side of development, I need a little help. I need to wire up the button to take the value typed in the text call the SearchResults controller (located in a file called ProductsController.cs) and populate a modal dialog box with the results. I have a partial razor page:
#model Sauron.Models.Products.ProductSearchResults
#foreach (var product in Model.ProductDetails)
{
<tr>
<td class="imageColumn">
#if (product.Image != null)
{
<div class="ajax-image-load">
<input type="hidden" id="BlockImageID" value="#product.Image.ImageId" />
<input type="hidden" id="BlockImageWidth" value="89" />
<input type="hidden" id="BlockImageHeight" value="89" />
<input type="hidden" id="BlockImageLoaderGif" value="/images/loader-circle-basic.gif" />
</div>
}
</td>
<td>
#product.SKU
<input type="hidden" id="editID" name="editID" value="#product.ProductId" />
</td>
<td>#(product.Description != null ? product.Description.Name : product.ReceiptName)</td>
#*<td>#(product.ColorId != null ? product.)</td> we might want to gather the color object as a property of this search class model*#
<td>
#{
var textColor = "";
if((product.InventorySummary ?? 0) <= 0){
textColor = "red-text";
}
}
<span class="#textColor">#((product.InventorySummary ?? 0).ToString())</span>
</td>
<td>
#if (product.ProductType != null ? product.ProductType.Equals(ProductType.PACK) : false)
{
<span>#(product.PackQty != null ? string.Format("{0} {1}", product.PackQty.Value, product.ProductType.ToString()) : product.ProductType.ToString())</span>
}
else if (product.ProductType != null ? product.ProductType.Equals(ProductType.CASE) : false)
{
<span>#(product.PackQty != null ? string.Format("{0} {1}", product.PackQty.Value, product.ProductType.ToString()) : product.ProductType.ToString())</span>
}
else
{
<span>#(product.ProductType != null ? product.ProductType.ToString() : "")</span>
}
</td>
</tr>
}
that will display the results. I need to display the results of the _SearchResults.cshtml page in a modal box.
I want to call the SearchResults method from the values entered in the text box to display the results.
Anyone's help is appreciated.
The problem was I was calling the controller by the wrong name. Once I got the right name, it started working.
Code:
$('#draftAddProduct').click(function () {
var keyWord = $('#draftProductModal').val();
$('#draftProductModal').load("#Url.Action("SearchResults","Products")?keywords=chair");
});
You can find an answer for this question here:
Bootstrap Modal Dialog - Loading Content from MVC Partial View
I have updated meteor application to version 0.8.0 from 0.7.0.1. Every changes tried to do but not able to figure out, how to change triple tag according to new version. Referred the following link and tried to do so but still getting error.
The link following is: https://github.com/meteor/meteor/wiki/Using-Blaze
The code of .html file is: Basically this {{{done }}} part. I tried to change according to the above link as {{> done}}. But then getting error as ""Reactive HTML attributes must either have a constant name or consist of a single {{helper}} providing a dictionary of names and values. A template tag of type INCLUSION is not allowed here.
""
<template name="subscribedKeyword">
<div class="issue" >
<div class="issue-content">
<h3>
{{category}}
<input id='check' class="checktype" name="mark" type="checkbox" value="1" {{{ done}}} />Get Notifications
<input type="hidden" name="mark" value="0" />
</h3>
</div>
</div>
</template>
The corresponding .js file code is: I think that there is no need to change anything in this file. As according to the above link, changes need to be done in the html file only.
Template.subscribedKeyword.done = function () {
// alert('inside done function');
var subscribedUsersOfThisDomain= Subscribed.findOne(this._id);
var subscribedPersons = subscribedUsersOfThisDomain.categorySubscribedUsers;
// alert('before if block in done function');
if(subscribedPersons && subscribedPersons.length)
{
var j;
var ch='';
// alert('before loop in done function');
for(j= 0;j< subscribedPersons.length;j++)
{
//alert('j '+j);
//alert('person '+person[j].username);
if(subscribedPersons[j].username === Meteor.user().username)
{
ch ="checked";
// alert('value of ch that is set'+ch);
break;
}
}
if(ch=== 'checked')
{
// alert('while returning value in if block');
return 'checked="checked"';
}
else
{
// alert('while returning value in else block');
return '';
}
}
else
return '';
};
Do let me know what changed need to be done. Thanks in advance
The simplest way I can see is:
<template name="subscribedKeyword">
<div class="issue" >
<div class="issue-content">
<h3>
{{category}}
<input id='check' class="checktype" name="mark" type="checkbox" value="1" checked={{done}} />Get Notifications
<input type="hidden" name="mark" value="0" />
</h3>
</div>
</div>
</template>
Template.subscribedKeyword.done = function () {
// alert('inside done function');
var subscribedUsersOfThisDomain= Subscribed.findOne(this._id);
var subscribedPersons = subscribedUsersOfThisDomain.categorySubscribedUsers;
// alert('before if block in done function');
if(subscribedPersons && subscribedPersons.length)
{
var j;
var ch='';
// alert('before loop in done function');
for(j= 0;j< subscribedPersons.length;j++)
{
//alert('j '+j);
//alert('person '+person[j].username);
if(subscribedPersons[j].username === Meteor.user().username)
{
ch ="checked";
// alert('value of ch that is set'+ch);
break;
}
}
if(ch=== 'checked')
{
// alert('while returning value in if block');
return "checked";
}
else
{
// alert('while returning value in else block');
return null;
}
}
else
return null;
};
According to https://github.com/meteor/meteor/wiki/Using-Blaze#conditional-attributes-with-no-value-eg-checked-selected
My app is based on the HotTowel template so it includes Durandal, Knockout & Breeze. I have a page with 3 tables side by side. The first table has a list of "templates', the 2nd table shows "sections" for the selected "template" and the 3rd table shows "items" for the selected "section". The "sections" and "items" tables are collections accessed via navigation properties. I find that I get intermittent binding issues. The data in the "templates" table always shows correctly, however related "sections" and "items" sometimes show correctly and other times one of the other is not populated. It would seem to be a timing issue. My view model and view are below. Am I just going about all of this the wrong way?
define(['services/dataservice', 'services/logger', 'services/model'],
function (ds, logger, model) {
var templates = ko.observableArray();
var selectedTemplate = ko.observable();
var selectedSection = ko.observable();
var selectedItem = ko.observable();
var newTemplateTitle = ko.observable();
var newSectionTitle = ko.observable();
var newItemTitle = ko.observable();
function activate() {
newTemplateTitle('');
newSectionTitle('');
newItemTitle('');
logger.log('Templates view activated', null, 'templates', false);
return ds.getTemplatePartials(templates, false, false);//.then(succeeded);
//function succeeded() {
// var firstTemplate = templates()[0];
// setSelectedTemplate(firstTemplate);
//}
}
templates.subscribe(function() {
var firstTemplate = templates()[0];
setSelectedTemplate(firstTemplate);
});
var deactivate = function () {
templates([]);
};
function refresh() {
return ds.getTemplatePartials(templates, true, false);
}
var viewAttached = function (view) {
bindEventToList(view, '#template-list', setSelectedTemplate);
bindEventToList(view, '#section-list', setSelectedSection);
bindEventToList(view, '#item-list', setSelectedItem);
return true;
};
var addTemplate = function () {
var newTemplate = ds.createEntity(model.entityNames.document);
newTemplate.title(newTemplateTitle());
newTemplate.isTemplate(true);
newTemplate.organisation(ds.getCurrentOrganisation()());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
templates.push(newTemplate);
templates.sort();
newTemplateTitle('');
}
};
var addSection = function () {
var newSection = ds.createEntity(model.entityNames.section);
newSection.title(newSectionTitle());
newSection.isTemplate(true);
newSection.document(selectedTemplate());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
newSectionTitle('');
}
};
var addItem = function () {
var newItem = ds.createEntity(model.entityNames.item);
newItem.title(newItemTitle());
newItem.isTemplate(true);
newItem.section(selectedSection());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
newItemTitle('');
}
};
var isTemplateSelected = function (template) {
if (template && selectedTemplate()) {
var thisId = ko.utils.unwrapObservable(selectedTemplate().id);
return ko.utils.unwrapObservable(template.id) == thisId;
}
return false;
};
var isSectionSelected = function (section) {
if (section && selectedSection()) {
var thisId = ko.utils.unwrapObservable(selectedSection().id);
return ko.utils.unwrapObservable(section.id) == thisId;
}
return false;
};
var isItemSelected = function(item) {
if (item && selectedItem()) {
var thisId = ko.utils.unwrapObservable(selectedItem().id);
return ko.utils.unwrapObservable(item.id) == thisId;
}
return false;
};
var vm = {
activate: activate,
deactivate: deactivate,
templates: templates,
//sections: sections,
//items: items,
selectedTemplate: selectedTemplate,
selectedSection: selectedSection,
selectedItem: selectedItem,
title: 'Template Maintenance',
refresh: refresh,
viewAttached: viewAttached,
addTemplate: addTemplate,
addSection: addSection,
addItem: addItem,
newTemplateTitle: newTemplateTitle,
newSectionTitle: newSectionTitle,
newItemTitle: newItemTitle,
isTemplateSelected: isTemplateSelected,
isSectionSelected: isSectionSelected,
isItemSelected: isItemSelected
};
return vm;
//#region internal methods
function setSelectedTemplate(data) {
if (data) {
selectedTemplate(data);
return selectedTemplate().entityAspect.loadNavigationProperty("sections").then(setFirstSectionSelected);
} else {
return false;
}
function setFirstSectionSelected() {
setSelectedSection(selectedTemplate().sections()[0]);
}
}
function setSelectedSection(data) {
if (data) {
selectedSection(data);
return selectedSection().entityAspect.loadNavigationProperty("items").then(setFirstItemSelected);
} else {
selectedSection();
selectedItem();
return false;
}
function setFirstItemSelected() {
setSelectedItem(selectedSection().items()[0]);
}
}
function setSelectedItem(data) {
if (data) {
selectedItem(data);
} else {
selectedItem();
}
}
function bindEventToList(rootSelector, selector, callback, eventName) {
var eName = eventName || 'click';
$(rootSelector).on(eName, selector, function () {
var item = ko.dataFor(this);
callback(item);
return false;
});
}
//#region
}
);
<section>
<div class="row-fluid">
<header class="span12">
<button class="btn btn-info pull-right push-down10" data-bind="click: refresh">
<i class="icon-refresh"></i> Refresh</button>
<h4 class="page-header" data-bind="text: title"></h4>
</header>
</div>
<div class="row-fluid">
<section class="span3">
<header class="input-append">
<input id="newTemplateName"
type="text"
data-bind="realTimeValue: newTemplateTitle"
placeholder="New template name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addTemplate, disable: newTemplateTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Templates</th>
</tr>
</thead>
<tbody>
<!-- ko foreach: templates -->
<tr id="template-list" data-bind="css: { 'selected': $root.isTemplateSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: templates().length"></span></span>
</article>
</section>
<section class="span5">
<header class="input-append">
<input id="newSectionName"
type="text"
data-bind="realTimeValue: newSectionTitle"
placeholder="New section name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addSection, disable: newSectionTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article data-bind="if: selectedTemplate">
<table class="table table-striped table-bordered table-hover" >
<thead>
<tr>
<th data-bind="text: 'Sections for ' + selectedTemplate().title()"></th>
</tr>
</thead>
<tbody>
<!-- ko foreach: selectedTemplate().sections() -->
<tr id="section-list" data-bind="css: { 'selected': $root.isSectionSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: selectedTemplate().sections().length"></span></span>
</article>
</section>
<section class="span4">
<header class="input-append">
<input id="newItemName"
type="text"
data-bind="realTimeValue: newItemTitle"
placeholder="New item name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addItem, disable: newItemTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article data-bind="if: selectedSection">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th data-bind="text: 'Items for ' + selectedSection().title()"></th>
</tr>
</thead>
<tbody>
<!-- ko foreach: selectedSection().items() -->
<tr id="item-list" data-bind="css: { 'selected': $root.isItemSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: selectedSection().items().length"></span></span>
</article>
</section>
</div>
Similar issue (same server, same client but sometimes some navigators not working in breeze) happened to me. In my opinion it can be a timing bug. Or the create/load order of entities count.
I've changed this paralell async load entities from server:
return promise = Q.all([
getPackage(),
getClubPartials(null, true),
getAddressPartials(null, true),
getEventPartials(null, true)
]).then(success);
to this get them one by one:
return getClubPartials(null, true).then(function () {
getAddressPartials(null, true).then(function () {
getEventPartials(null, true).then(function () {
return getPackage().then(success);
})
})
});
And my problem gone!
There is just a lot of code to wade through and try to make sense of in the imagination.
You seem to say it works some of the time. That does sound like a timing issue.
One thing that is disturbing is the async methods (e.g. setSelectedTemplate) that return either false or a promise; not sure why the inconsistency. But that is probably not the real problem.
You could try putting a setTimeout(..., 10) before exiting the async methods. See if that changes the behavior.
If that doesn't reveal it, you'll have to boil it down to just those the essentials that reveal the problem.
Sadly no sudden flash of insight today.
Update June 3
My first concern is that some of your methods return promises and some return the value false. I'd feel more comfortable if they all returned promises. Look at Q.resolve().
Other code baffles me. For example, what is going on in the many variations on this pattern:
function setSelectedItem(data) {
if (data) {
selectedItem(data);
} else {
selectedItem();
}
}
The else{...} isn't doing anything useful. It unwraps the selectedItem property ... and discards the value. What is the point?
And what is the difference between this:
thisId = ko.utils.unwrapObservable(selectedTemplate().id); // obscure
and this?
thisId = selectedTemplate().id(); // clear
Are you unsure whether selectedTemplate().id is a KO observable? The only reason to use unwrapObservable is when you are unsure.
As for timing, you can let KO know that it should re-fresh a binding by calling valueHasMutated() on an observable. For example:
function setFirstItemSelected() {
setSelectedItem(selectedSection().items()[0]);
selectedItem.valueHasMutated();
}
It might help. I don't know ... you're stacking a long chain of dependencies and it isn't easy to see which are bailing out when. That would take study of actual data flows as well as the code. You cannot reasonably expect your StackOverflow audience to work that hard for free.
Try cutting this way down to a super-simple example that displays the troublesome behavior.
Best of luck.
Working on learning bootstrap and knockout.js. This is more of a knockout question.
I would like to populate a new row of a table (using addSeat function), and if the name field on that new row is empty, add the bootstrap 'error' class to the row. It is empty by default. Once the name field is entered, the style should change to 'success'.
The basic code is taken from the Seat Reservation samples. Here is the markup:
<div id="food" class="span10">
<h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th>Passenger name</th><th>Meal</th><th>Surcharge</th><th></th>
</tr></thead>
<tbody data-bind="foreach: seats">
<tr data-bind="css: isnameBlank">
<td><input data-bind="value: name" /></td>
<td><select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select></td>
<td data-bind="text: formattedPrice"></td>
<td><i class="icon-remove"></i>Remove</td>
</tr>
</tbody>
</table>
<button data-bind="click: addSeat, enable: seats().length < 8">Reserve another seat</button>
<h3 data-bind="visible: totalSurcharge() > 0">
Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
</h3>
</div>
Here is the js file:
// Class to represent a row in the seat reservations grid
function SeatReservation(name, initialMeal) {
var self = this;
self.name = ko.observable(name);
self.meal = ko.observable(initialMeal);
self.formattedPrice = ko.computed(function () {
var price = self.meal().price;
return price ? "$" + price.toFixed(2) : "None";
});
self.isnameBlank = ko.computed(function () {
var ib = self.name().length;
console.log(ib);
return ib == 0 ? "warning" : "success";
}, self);
}
// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
var self = this;
// Non-editable catalog data - would come from the server
self.availableMeals = [
{ mealName: "Standard (sandwich)", price: 0 },
{ mealName: "Premium (lobster)", price: 34.95 },
{ mealName: "Ultimate (whole zebra)", price: 290 }
];
// Editable data
self.seats = ko.observableArray([
new SeatReservation("Steve", self.availableMeals[0]),
new SeatReservation("Bert", self.availableMeals[0])
]);
// Computed data
self.totalSurcharge = ko.computed(function () {
var total = 0;
for (var i = 0; i < self.seats().length; i++)
total += self.seats()[i].meal().price;
return total;
});
// Operations
self.addSeat = function () {
self.seats.push(new SeatReservation("", self.availableMeals[0]));
}
self.removeSeat = function (seat) { self.seats.remove(seat) }
}
ko.applyBindings(new ReservationsViewModel(), document.getElementById('food'));
When I run this the console logs the correct length (the ib variable), but the css class does not change.
Thank you for your help!
Where you have this line:
var ib = self.name.length;
You should be doing this:
var ib = self.name().length;
This seems to be working just fine when I test it in Chrome. Here is the jsFiddle:
http://jsfiddle.net/Xfv2g/
The only thing I can assume is that you are expecting it to change as they type. In order to do that you will have to change when the name field binds by putting the valueUpdate: 'afterkeydown' modifier to the value binding.
Here is the same fiddle with that being the only difference.
http://jsfiddle.net/Xfv2g/1/