Update the notification counter in mvc 4 - wcf

I want to sync the notification counter on both sides at a time. The attached image will make you understand easily what i need to do on which I am stuck from quite a few days.
Image:
The Right Side of the notification bell is in Layout:
<div class="header-top">
<h2 style="width:100%">#ViewBag.Heading</h2>
<a class="info sprite" id="lnkInfo"></a>
#{
if(ViewBag.ShowNotification != null && ViewBag.ShowNotification) {
<span class="notifications-icon"><em>#ViewBag.NotificationCount</em></span>
}
}
</div>
The Left Notification Bell is in View.
Code:
<div class="head">
<span class="notifications-icon"><em>#Model.Announcement.Count</em></span>
<h3>Notifications</h3>
</div>
Jquery Ajax Call to Controller Action:
function UpdateNotification(id) {
var json = { "AnnouncementID": id };
$.ajax({
type: 'POST',
url: '#Url.Action("UpdateNotificationData", "Home")',
contentType: 'application/json; charset=utf-8',
data: '{"AnnouncementID":' + id + '}',
dataType: 'json',
cache: false,
success: function (data) {
if (data) {
updatenotificationUI(id);
}
}
})
}
function updatenotificationUI(id) {
var $notificaitonContainer = $(".notifications");
if (id != null) {
var $li = $notificaitonContainer.find("li[id=" + id + "]");
if ($li != null) {
$li.slideUp("slow", function () {
$(this).remove();
var legth = $notificaitonContainer.find("#listing li").length;
if (legth > 0)
$notificaitonContainer.find("em").html(legth);
else
$notificaitonContainer.find("em").html("");
});
}
}
else {
$notificaitonContainer.find("ul").html("");
$notificaitonContainer.find("em").html("");
}
}
Home Controller :
public ActionResult UpdateNotificationData(string AnnouncementID)
{
var announcements = new AnnouncementResponse() { Announcement = new List<Announcement>() };
if (IsUserAuthenticated)
return RedirectToAction("Index", "Account");
announcements = _contentManager.Announcement();
var item = announcements.Announcement.Where(p => p.AnnouncementID == Convert.ToInt32(AnnouncementID)).FirstOrDefault();
announcements.Announcement.Remove(item);
ViewBag.NotificationCount = announcements.Announcement.Count;
return Json(new { success = true });
}
But the Notification Bell in Layout doesnt update with the viewbag value or even when the model is assigned to it.
Please provide a solution for this.

You're only updating one of the two notifications. First you find a containing element:
var $notificaitonContainer = $(".notifications");
The HTML in the question doesn't have any elements which match this, so I can't be more specific. But just based on the naming alone it sounds like you're assuming there's only one such container.
Regardless, you then choose exactly one element to update:
var $li = $notificaitonContainer.find("li[id=" + id + "]");
(This can't be more than one element, since id values need to be unique.)
So... On your page you have two "notification" elements. You're updating one of them. The solution, then, would be to also update the other one. However you identify that elements in the HTML (jQuery has many options for identifying an element or set of elements), your updatenotificationUI function simply needs to update both.

Related

Jqgrid change nav properties on callback function

i try to change the navbar properties on a jqgrid in a callback function without succes.
The grid is display afeter user is chosing a period. Depend on either the period is open or close user can or cannot edit, add, delete rows. So the navbar need to change properties dynamically.
My code look like that:
$('#mygrid').jqGrid({
// some properties of my grid that works fine
pager : '#gridpager'
});
$("#mygrid").bind("jqGridLoadComplete",function(){
$.ajax({
url: 'checkifperiodopen.php',
data: {
$("#period").val()
},
success: function(data){
if(period==='open'){
jQuery("#mygrid").jqGrid('navGrid','#gridpager',{add:false,edit:false,del:true,search:true,refresh:true});
}
if(period==='close'){
jQuery("#mygrid").jqGrid('navGrid','#gridpager',{add:true,edit:true,del:true,search:true,refresh:true});
}
}
});
});
$('#validChossenPeriod').click(function () {
ajax call to get data on choosen period
success:function(data){
$("#mygrid").jqGrid('clearGridData');
$("#mygrid").jqGrid('setGridParam', { datatype: 'local'});
$("#mygrid").jqGrid('setGridParam', { data: data});
$("#mygrid").trigger('reloadGrid');
}
});
I finally found the answer by show or hide the div that include the navgrid button:
grid = $("#mygrid");
gid = $.jgrid.jqID(grid[0].id);
var $tdadd = $('#add_' + gid);
var $tdedit = $('#edit_' + gid);
var $tddel = $('#del_' + gid);
$("#mygrid").jqGrid('navGrid','#gridpager',{add:true,edit:true,del:true,search:true,refresh:true});
condition if false =
$tdadd.hide();
$tdedit.hide();
$tddel.hide();
if true =
$tdadd.show();
$tdedit.show();
$tddel.show();
Why so complex? There is a other clear way to do this
var view_buttons = true;
if(condition_to_hide) {
view_buttons = false;
}
$("#mygrid").jqGrid('navGrid','#gridpager', { add:view_buttons, edit:view_buttons, del:view_buttons, search:true, refresh:true});

Shopify Slate - prevent go to cart page on add to cart

I'm building a theme with Slate and I have been researching how to prevent the default function of going to the cart page after you click add to cart on a product page.
All the answers I have gotten thus far have lead to dead ends. I also tried to load Cart.js onto the theme and it didn't let me because there's some liquid code mixed in with the initialize script.
Really looking for help to prevent a theme built with Slate from automatically going to the cart page once you click add to cart. Thanks!
The redirect is probably based on a form submission, so you just need to use jQuery's preventDefault method when the form is submitted.
$('form[action^="/cart/add"]').on('submit', function(evt) {
evt.preventDefault();
//add custom cart code here
});
Found a solution using Ajaxify cart (https://help.shopify.com/themes/customization/products/add-to-cart/stay-on-product-page-when-items-added-to-cart)
To get this to work with Slate, you need to follow the instructions and make a few changes once they are all followed. Here's what I did.
I had to take all the jQuery in the script tags and place it in a new file under scripts > vendor > vendor.js
/**
* Module to ajaxify all add to cart forms on the page.
*
* Copyright (c) 2015 Caroline Schnapp (11heavens.com)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
Shopify.AjaxifyCart = (function($) {
// Some configuration options.
// I have separated what you will never need to change from what
// you might change.
var _config = {
// What you might want to change
addToCartBtnLabel: 'Add to cart',
addedToCartBtnLabel: 'Thank you!',
addingToCartBtnLabel: 'Adding...',
soldOutBtnLabel: 'Sold Out',
howLongTillBtnReturnsToNormal: 1000, // in milliseconds.
cartCountSelector: '.cart-count, #cart-count a:first, #gocart p a, #cart .checkout em, .item-count',
cartTotalSelector: '#cart-price',
// 'aboveForm' for top of add to cart form,
// 'belowForm' for below the add to cart form, and
// 'nextButton' for next to add to cart button.
feedbackPosition: 'nextButton',
// What you will never need to change
addToCartBtnSelector: '[type="submit"]',
addToCartFormSelector: 'form[action="/cart/add"]',
shopifyAjaxAddURL: '/cart/add.js',
shopifyAjaxCartURL: '/cart.js'
};
// We need some feedback when adding an item to the cart.
// Here it is.
var _showFeedback = function(success, html, $addToCartForm) {
$('.ajaxified-cart-feedback').remove();
var feedback = '<p class="ajaxified-cart-feedback ' + success + '">' + html + '</p>';
switch (_config.feedbackPosition) {
case 'aboveForm':
$addToCartForm.before(feedback);
break;
case 'belowForm':
$addToCartForm.after(feedback);
break;
case 'nextButton':
default:
$addToCartForm.find(_config.addToCartBtnSelector).after(feedback);
break;
}
// If you use animate.css
// $('.ajaxified-cart-feedback').addClass('animated bounceInDown');
$('.ajaxified-cart-feedback').slideDown();
};
var _setText = function($button, label) {
if ($button.children().length) {
$button.children().each(function() {
if ($.trim($(this).text()) !== '') {
$(this).text(label);
}
});
}
else {
$button.val(label).text(label);
}
};
var _init = function() {
$(document).ready(function() {
$(_config.addToCartFormSelector).submit(function(e) {
e.preventDefault();
var $addToCartForm = $(this);
var $addToCartBtn = $addToCartForm.find(_config.addToCartBtnSelector);
_setText($addToCartBtn, _config.addingToCartBtnLabel);
$addToCartBtn.addClass('disabled').prop('disabled', true);
// Add to cart.
$.ajax({
url: _config.shopifyAjaxAddURL,
dataType: 'json',
type: 'post',
data: $addToCartForm.serialize(),
success: function(itemData) {
// Re-enable add to cart button.
$addToCartBtn.addClass('inverted');
_setText($addToCartBtn, _config.addedToCartBtnLabel);
_showFeedback('success','<i class="fa fa-check"></i> Added to cart! View cart or continue shopping.',$addToCartForm);
window.setTimeout(function(){
$addToCartBtn.prop('disabled', false).removeClass('disabled').removeClass('inverted');
_setText($addToCartBtn,_config.addToCartBtnLabel);
}, _config.howLongTillBtnReturnsToNormal);
// Update cart count and show cart link.
$.getJSON(_config.shopifyAjaxCartURL, function(cart) {
if (_config.cartCountSelector && $(_config.cartCountSelector).size()) {
var value = $(_config.cartCountSelector).html() || '0';
$(_config.cartCountSelector).html(value.replace(/[0-9]+/,cart.item_count)).removeClass('hidden-count');
}
if (_config.cartTotalSelector && $(_config.cartTotalSelector).size()) {
if (typeof Currency !== 'undefined' && typeof Currency.moneyFormats !== 'undefined') {
var newCurrency = '';
if ($('[name="currencies"]').size()) {
newCurrency = $('[name="currencies"]').val();
}
else if ($('#currencies span.selected').size()) {
newCurrency = $('#currencies span.selected').attr('data-currency');
}
if (newCurrency) {
$(_config.cartTotalSelector).html('<span class=money>' + Shopify.formatMoney(Currency.convert(cart.total_price, "{{ shop.currency }}", newCurrency), Currency.money_format[newCurrency]) + '</span>');
}
else {
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}"));
}
}
else {
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}"));
}
};
});
},
error: function(XMLHttpRequest) {
var response = eval('(' + XMLHttpRequest.responseText + ')');
response = response.description;
if (response.slice(0,4) === 'All ') {
_showFeedback('error', response.replace('All 1 ', 'All '), $addToCartForm);
$addToCartBtn.prop('disabled', false);
_setText($addToCartBtn, _config.soldOutBtnLabel);
$addToCartBtn.prop('disabled',true);
}
else {
_showFeedback('error', '<i class="fa fa-warning"></i> ' + response, $addToCartForm);
$addToCartBtn.prop('disabled', false).removeClass('disabled');
_setText($addToCartBtn, _config.addToCartBtnLabel);
}
}
});
return false;
});
});
};
return {
init: function(params) {
// Configuration
params = params || {};
// Merging with defaults.
$.extend(_config, params);
// Action
$(function() {
_init();
});
},
getConfig: function() {
return _config;
}
}
})(jQuery);
Shopify.AjaxifyCart.init();
Next I made sure that this file was being called to the main vendor.js file using this code in scripts > vendor.js
/*!
* ajaxify-cart.js
*/
// =require vendor/ajaxify-cart.js
Last thing I had to do was edit out the liquid markup that was in the ajaxify-cart.js file. Since it is a .js file the liquid markup was making it malfunction. Here's the lines where I replaced liquid markup:
if (newCurrency) {
$(_config.cartTotalSelector).html('<span class=money>' + Shopify.formatMoney(Currency.convert(cart.total_price, "CAD", newCurrency), Currency.money_format[newCurrency]) + '</span>');
}
else {
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price));
}
}
else {
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price));
}
It's a bit hacky but so far it is working with my slate theme.
I'm open to suggestions for improvement. Thanks.

MVC Failed to load resource: the server responded with a status of 500 (Internal Server Error)

I have problem with my first MVC project. I'm trying to change values of DropDownList of surnames when select DropDownList of doctor types. I think my action is working. But I cannot use result in view.
Here my codes:
$(function () {
$('select#mCB').change(function () {
var docId = $(this).val();
$.ajax({
dataType: 'json',
data: 'spec=' + docId,
method: 'GET',
url: 'LoadDoctors',
success: function (data) {
$.each(data, function (key, Docs) {
$('select#shCB').append('<option value="0">Select One</option>');
$.each(Docs, function (index, docc) {
$('select#shCB').append(
'<option value="' + docc.Id + '">' + docc.Name + '</option>');
});
});
},
error: function (docID) {
alert(' Error !');
}
});
});
});
Actions:
public static List<Docs> GetDoctorBySpec(string spec)
{
List<Docs> list = new List<Docs>();
string query = "select ID, Familiyasi, Speciality from Doktorlar where Speciality=#spec";
SqlConnection Connection = new SqlConnection(DataBase.ConnectionString);
Connection.Open();
SqlCommand cmd = new SqlCommand(query, Connection);
cmd.Parameters.Add("#spec", spec);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
list.Add(new Docs
{
Id = dr.GetString(0),
Name = dr.GetString(1)
});
}
return list;
}
enter code here
enter code here
[HttpGet]
public ActionResult LoadDoctors(string spec)
{
List<Docs> list = DoctorsService.GetDoctorBySpec(spec);
if (list == null)
{
return Json(null);
}
return Json(list);
}
And here my DropDownLists:
<div class="editor-label">
#Html.LabelFor(model => model.DoktorTuri)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.DoktorTuri, new SelectList(ViewBag.Vrachlar), new { #id = "mCB", #class = "vrachlar" })
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Shifokori)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Shifokori, Enumerable.Empty<SelectListItem>(), new { #id = "shCB", #class = "vrachlar" })
</div>
Where is my mistake? Thanks for answers
A 500 (Internal Server Error) almost always means that your throwing an exception on the server. Best guess is in your case it's because your method
DoctorsService.GetDoctorBySpec(spec);
does not accept null as a parameter and the value of spec is null because your never pass it value to the controller. As stann1 has noted your ajax option needs to be
data: {spec: docId},
In addition, you do not specify the JsonRequestBehavior.AllowGet parameter which means the method will fail.
All of this can be easily determined by debugging your code, both on the server and by using your browser tools (in particular the Network tab to see what is being sent and received along with error messages)
However this is only one of many problems with your code.
Firstly, unless Docs contains only 2 properties (the values you need for the option's value attribute and display text), your unnecessarily wasting bandwidth and degrading performance by sending a whole lot of data to the client which is never used. Instead, send a collection of anonymous objects
[HttpGet]
public ActionResult LoadDoctors(string spec)
{
List<Docs> list = DoctorsService.GetDoctorBySpec(spec);
if (list == null)
{
return Json(null, JsonRequestBehavior.AllowGet);
}
var data = list.Select(d => new
{
Value = d.Id,
Text = d.Name
});
return Json(data, JsonRequestBehavior.AllowGet);
}
Next, your script will only ever generate multiple <option value="0">Select One</option> elements (one for each item in the collection) because data in $.each(data, function (key, Docs) { is your collection, and Docs is the item in the collection. Your second $.each() function will never produce anything because Docs is not a collection.
You script should be (note I have use the short version $.getJSON() rather than the longer $.ajax() and also used the default id attributes generated by the html helpers - its not clear why you would want to change the id's using new { id = "mCB" }?)
var url = '#Url.Action("LoadDoctors")'; // never hard code your url's
var shifokori = $('#Shifokori'); // cache it
$('#DoktorTuri').change(function () {
$.getJSON(url, { spec: $(this).val() }, function(data) {
if (!data) { // only necessary depending on the version of jquery
// oops
}
// clear existing options and append empty option with NULL value (not zero)
// so validation will work
shifokori.empty().append($('<option></option>').val('').text('Select One'));
$.each(data, function (index, doc) {
shifokori.append($('<option></option>').val(doc.Value).text(doc.Text));
});
}).fail(function (result) {
// oops
});
});
The data param of the call needs to be a Javascript object literal:
$.ajax({
dataType: 'json',
data: {spec: docId},
method: 'GET',
....
});
Also, try to debug your controller and use a rest extension (or Fiddler) to test the payload, you would catch such error easily yourself ;)

Can not find a way to check or uncheck checkbox in my view

I have a partial view ,which I throw to another view ,In my partial view there is a checkbox which is checked by default I want to change its current (checked/unchecked) option from main view. Here is my partial view code:
<td class="sevenCol" name="sevenCol">
<input type="checkbox" checked/>
</td>
Below shows partial view content:
$("#btnSubmit").click(function () {
var mobnum = $("#mobNo").val();
var message = $("#txtMessage").val();
alert(mobnum);
$.ajax({
url: "SmsSendFromOneToOne",
type: "POST",
data: { contactList: mobnum, message: message },
success: function (data) {
$("#gridGenerate").html(data);
}
});
});
Below verifies checkbox is checked or unchecked but it always returns true so how can I fix this?
$("#sendbtn").click(function () {![enter image description here][1]
var maskId = $("#MASKLIST").val();
var campaignName = $("#campaignName").val();
var dataArray = {};
$(".loadingmessage").show();
$("#gridGenerate tr").each(function (iii, val) {
var trId = $(this).attr("id");
var isChecked = $('td[name=sevenCol]').find('input[type="checkbox"]').is(':checked');
//alert(isChecked);
if (isChecked) {
dataArray[iii] = {
'mobile': $(this).find(".secondCol").text(),
'message': $(this).find(".thirdCol").text(),
'type': $(this).find(".fifthCol").text()
};
}
});
Controller:
[HttpPost]
public ActionResult SmsSendFromOneToOne(string contactList, string message)
{
IList<GridPanel> cellInfoForForm1 = _smsService.GetForm1ForViewing(contactList, message);
return PartialView("partialGridPanel", cellInfoForForm1);
}
Thanks
it is a lot simpler if you put the selector directly on the field. try adding a class to your checkbox
<input type="checkbox" class="mobileCheck" checked/>
then in your script you can replace
var isChecked = $('td[name=sevenCol]').find('input[type="checkbox"]').is(':checked');
with
var isChecked = $('.mobileCheck').is(':checked');
Finally got my answer ,As i am binding a partial view and checkbox exits in it so i have to use jquery .live( events, data, handler(eventObject) )to solve the issue ..
$( selector ).live( events, data, handler );
Again thanks for responding

MVC4 .Net , controls on hidden fields

I wonder if it's possible to have controls (dataanotation) on hidden fields (HiddenFor or hidden EditorFor) ?
I don't think so, but we never know.
There are a lot of posts on how to hide EditorFor such as :
TextBoxFor vs EditorFor, and htmlAttributes vs additionalViewData
In my case,in a view I have a jquery call to a WCF REST service, that in success case fill my EditorFor. I would like that the Required DataAnotation to be applied on that EditorFor, would it be possible ?
I think that as long as the EditorFor is invisible the DataAnotation cannot be applied. Would it have a way to apply the DataAnotation on the hidden EditorFor ?
Here is the code :
To hide the EditorFor :
#Html.EditorFor(model => model.VilleDepart, "CustomEditor", new {style = "display:none;" })
The CustomEditor :
#{
string s = "";
if (ViewData["style"] != null) {
// The ViewData["name"] is the name of the property in the addtionalViewData...
s = ViewData["style"].ToString();
}
}
#Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { style = s })
the model :
string _VilleDepart;
[Required]
[Display(Name = "Ville Départ")]
public string VilleDepart
{
get
{
if (Commune != null) {
return Commune.Commune1;
}
return _VilleDepart;
}
set {
_VilleDepart = value;
}
}
The JQuery call to WCF REST Service :
$(document).ready(function () {
$([document.getElementById("IVilleDepart"), document.getElementById("IVilleArrivee")]).autocomplete({
source: function (request, response) {
$.ajax({
cache: false,
type: "GET",
async: false,
dataType: "json",
url: GetSearchCommunetURl + "(" + request.term + ")",
success: function (data) {
//alert(data);
response($.map(data, function (item) {
return {
label: item['Commune'] + ' (' + item['CodePostal'] + ')',
val: item
}
}))
},
error: function (response) {
alert("error ==>" + response.statusText);
},
failure: function (response) {
alert("failure ==>" + response.responseText);
}
});
},
select: function (e, i) {
if (e.target.id == "IVilleDepart") {
VilleDepart = i.item.val;
EVilleDepart.value = VilleDepart.Commune;
ECodePostalDepart.value = VilleDepart.CodePostal;
ECodeINSEEDepart.value = VilleDepart.CodeINSEE;
}
if (e.target.id == "IVilleArrivee") {
VilleArrivee = i.item.val;
EVilleArrivee.value = VilleArrivee.Commune;
ECodePostalArrivee.value = VilleArrivee.CodePostal;
ECodeINSEEArrivee.value = VilleArrivee.CodeINSEE;
}
},
minLength: 2
});
});
If I don't hide the EditorFor I can see it is correctly filled after the WCF REST service call and the Required DataAnotation is applied.
There are other way to hide the EditorFor, for instance to apply the style='width:0px;height:0px'
It hides but disable the Required DataAnotation,
if I apply the style='width:0px;height:1px', we don't see a lot of the EditorFor but the Required DataAnotation is active.
I've seen an answer at http://www.campusmvp.net/blog/validation-of-hidden-fields-at-the-client-in-asp-net-mvc
(but it seems i had badly searched precedently, the validation of hidden field is treated in some blogs and sites).
To active the validation of hidden fields, you just have to add this little javascript line :
$.validator.setDefaults({ ignore: null });
and it works !
Apparently it doesn't work with mvc2, but works since mvc3.