Changing content of variable using jquery? - c#

I am currently working with an Sitecore MVC project, in which i have some problems understanding how I can alter my model, which currently consist two of a string tech and string add dynamically using jQuery.
My idea was to have the index file like this
var global_var1 = "";
var global_var2 = "";
<div class = "upper">
<div class= "tech_field" >
#Model.tech = global_var1
</div>
<div class= "add_field" >
#Model.add = global_var2
</div>
</div>
And then with the jQuery do something like
$('upper').find('tech_field')
But how do i exactly modify the value or the variable, i know how to find the div which contains the value, but not the exact variable.

#Model is a variable defined only on the server-side when the page is generated. On the client side in the browser, you do not have access to server-side variables.
#Model.tech renders the tech property value at that location in the page.
So this code:
<div class= "tech_field" >
#Model.tech = global_var1
</div>
Will render this if #Model.tech contains "Content of the tech property":
<div class= "tech_field" >
Content of the tech property = global_var1
</div>
If you want to use JavaScript to render your model property values, you can do it like this:
<script>
// Sets JavaScript variables with the content of server-side model property values
var model_tech = "#Model.tech";
var model_add = "#Model.add";
</script>
<div class="upper">
<div class="tech_field"></div>
<div class="add_field"></div>
</div>
<script>
$('.tech_field').text(model_tech); // Sets the DOM element value to the content of the JavaScript variable
var techValueFromDom = $('.tech_field').text(); // Reads the DOM to read the text.
</script>
However, there is no easy way to call Sitecore to update data stored in Sitecore items from JavaScript code.

Related

show a div of image only in homepage and hide from other pages

<div class="container">
#section HeroSection{
#foreach (var category in Model.AllCategory.Where(m => m.IsFeatured).FirstOrDefault().CategoryPictures.Select(m => m.Picture).Distinct())
{
<div class="hero__item set-bg" data-setbg="/FileStore/images/#category.Url">
<div class="hero__text">
<span>FRUIT FRESH</span>
<h2>Vegetable <br />100% Organic</h2>
<p>Free Pickup and Delivery Available</p>
SHOP NOW
</div>
</div>
}
}
</div>
</div>
</div>
}
</div>
I tried to #Render the //#section HeroSection// as false in _layout page .so that it will only appear in home/index ..not in other pages!
I can think of 2 approaches.
the first one is not so practical which is making 2 different layouts, one without the div and one with it. And you can change the layout of the homepage in the razor file like this
#{Layout = "YourNewLayOut"}
The other approach which I think it's better is to use JavaScript.
you can use window.location.href to get the current url and check if it's the url of the home page you target the div and make hidden otherwise visible.
your function should look like this :
function someFunctionName() {
let div = document.querySelector("#yourDiv");
if (window.location.href === "your home page url ") {
div.style.display = "none";
} else {
div.style.display = "block or flex or what ever you're using";
}
}
and then Invoke this function on loading like this
window.onload = function() {
someFunctionName();
};

Extract text from a div

I am trying to make a DropDownList using divs and jquery (so that I can style it as I want)...and its working but the problem is I cant get the selected value from the list..
After selection of the option I am copying the selected value into the a div.. and I want to extract this using c# (in .aspx.cs page)... I've tried to do it using string builder and innerHtml(after adding runat="server" to the div).. but it doesn't work ...code is as follows
.aspx Page:
<div class="ddl">
<div id="lowertriangle" class="lowertriangle"></div>
<div id="uppertriangle" class="uppertriangle"></div>
<div id="label" class="labeldiv_dd" runat="server"></div>//***This is the div from which I want to extract value***
<div id="options" class="optionsidv_dd">
<ul id="options_ul">
<li id="0">Select One Option</li>
<li id="1">Option 1</li>
<li id="2">Option 2</li>
<li id="3">Option 3</li>
<li id="4">Option 4</li>
<li id="5">Option 5</li>
</ul>
</div>
</div>
aspx.cs page
Method 1 that I tried:
string sel_text = label.InnerHtml;
display_sel_value.Text = sel_text.ToString();
2nd method:
var sb = new StringBuilder();
label.RenderControl(new HtmlTextWriter(new StringWriter(sb)));
string s = sb.ToString();
Kindly point out my mistakes and help me in this regard(in extracting innerHTML of the div that is).
Thanks
No, putting content in a div won't work.
Your example isn't complete enough to see all that happens, but let's assume that you're in a standard <form>, you're setting the div's inner HTML to a value with Javascript and then you're submitting in the standard way.
Then one way to do what you want is to use a hidden input and setting its value attribute instead of its contents.
<input id="label" class="labeldiv_dd" runat="server" type="hidden">
In the codebehind, the C# can retrieve the value from this control after submitting with the .Value property.
Ok guys thx for your replies..I found a way around the problem...I used HiddenField control to store the selected value using jQuery like so
$("#options_ul li").click(function () {
var text = this.innerHTML;
***$('#<%= selectedvalue.ClientID %>').val(text);***
$("#options_ul li").css("background-color", "#c2c2c2");
$(this).css("background-color", "white");
//var prev = this.id;
//document.getElementById("label").innerHTML = text;
toggleHeight();
});
and then accessed it server side using
selectedvalue.value;
PS: "selectedvalue" is id of the hiddenfield control

two page layouts into one view

I would like some advice on this matter. I have a view page that will display a number of users. One view is to display users in a grid (gallery like) of their images. Second view is to display the same users but by their name in a list layout. I will have a toggle button on the page to switch between the two. What is the best way to go about it? Having two separate view pages or have a partial view of some sort?
Update Code after suggestion below
<div data-bind="template: {name:'grid-template'}"></div>
<div data-bind="template: {name:'list-template'}"></div>
<script style="float:left" type="text/html" id ="grid-template">
<section " style="width:100%; float:left">
<section id="users" data-bind="foreach: Users">
<div id="nameImage">
<figure id="content">
<img width="158" height="158" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
<figcaption>
<a title="Email" id="emailIcon" class="icon-envelope icon-white" data-bind="attr:{'href':'mailto:' + Email()}"></a>
<a title="Profile" id="profileIcon" class="icon-user icon-white"></a>
</figcaption>
</figure>
<p data-bind="text:Name"></p>
</div>
</section>
</section>
</script>
<script style="float:left" type="text/html" id="list-template">
<div data-bind="foreach: Users">
<div style="width:60%; float:left; margin:10px; height:58px">
<img style="float:left; margin-right:5px" width="58" height="58" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
<p style="height:58px; float:left; vertical-align:central" data-bind="text:Name"></p>
<a style="float:right" title="Profile" class="icon-user icon-black"></a>
<a style="float:right" title="Email" class="icon-envelope icon-black" data-bind="attr:{'href':'mailto:' + Email()}"></a>
</div>
</div>
</script>
Knockout Script File
$.views.User.UserViewModel = function (data) {
var self = this;
self.Name = ko.observable(data.Name);
self.Email = ko.observable(data.Email);
self.ContentRole = ko.observable(data.ContentRole);
self.MD5Email = ko.observable(data.MD5Email);
self.GravatarUrl = ko.computed(function () {
return 'http://www.gravatar.com/avatar/' + self.MD5Email() + '?s=300&d=identicon&r=G';
});
self.renderMode = ko.observable('grid');
self.displayTemplate = ko.computed(function () {
return self.renderMode() + '-layout-template';
});
};
Personally, I like having clean isolated small little Partial Views especially if it is going to be regular HTTP POST.
However, based on the assumptions I am making below, I think I can suggest a better implementation design.
My Assumption
You have
Index.cshtml Parent view to display a list Users.
JSON object array containing your list of Users
Based on what I see, you are using KnockoutJS.
Read the KnockoutJS Template Binding especially the "Note 5: Dynamically choosing which template is used" part.
It kind of makes it easier to do what you are doing if you are using KnockoutJS or something similar.
You simply have toggle between the two rendering templates.
<script type="text/html" id="gallery-layout-template"> ... </script>
<script type="text/html" id="listing-layout-template"> ... </script>
<div id="divOutputContainer"
data-bind="template: { name: displayTemplate, foreach: users }"></div>
<script type="text/javascript">
$(document).ready(function() {
// I am just writing out a dummy User array here.
// Render out your User Array JSON encoded using JSON.NET.
var myUsers = [
{ "id" : 1, "name": "User 1" },
{ "id" : 2, "name": "User 2" }
];
// here is your KnockoutJS View Model "class"
function MyKoViewModel(users) {
var self = this;
self.users = ko.observableArray(users);
// Toggle this renderMode observable's value
// between 'listing' and 'gallery' via your Toggle button click event handler
self.renderMode = ko.observable( 'gallery' );
self.displayTemplate = function(user) {
// this will return 'gallery-layout-template' or 'listing-layout-template'
return self.renderMode() + '-layout-template';
}
}
ko.applyBindings( new MyKoViewModel( myUsers ) );
});
</script>
So with that technique, you don't need to make an AJAX call every time to refresh the view with a different rendering template.
You have all your data that you want to display as a client-side JavaScript KnockoutJS view model.
Then, just switch the client-side rendering template using KnockoutJS.
Must more efficient :-)
NOTE
I have a feeling, you might have to use the ko.computed() for the MyKoViewModel's displayTemplate() function like this.
self.displayTemplate = ko.computed(function() {
return self.renderMode() + '-layout-template';
}

Dynamic load of html code

In my Asp.net website I have a repeater which loads dynamically from code-behind. In code outside the repeater I have an "add" button. On click, I want to add the same controls from repeater asynchronously. On click of the "add" button function NewRow() is called:
function NewRow(){
var guid = jQuery.guid++;
var panel = $('#MainContent_Panel1');
var textboxText = $('#MainContent_TextBox');
panel.after("<span LabelGroup="+i+">Test Text:</span>
<span TextGroup="+i+">"+textboxText.val()+"<br /></span>
<span LabelGroup="+i+">Test Text : </span>
<input type='text' customID="+guid+"/>
<input type='button' Class='Button' ButtonGroup='"+i+"' value='Button Text' /></br>
");
i++;
}
I hate what I am currently doing, because there is so much hardcoded code. Is there any way I can make it more dynamic?
And is there any way to place my newly added row more precisely in dynamic control like repeater?
You could try a templating engine like mustache.js, or you can do it by hand like this:
In your HTML, include a script tag, with type="text/html". This will tell the rendering engine to do not try to render the contents. Inside this tag, you will write the template code for each column.
I marked each variable section as $variable:
$i
$textboxText
$guid
​<script type="text/html"​​​​​​​​​​​​​​​​ id="template">
<span LabelGroup='$i'>Test Text:</span>
<span TextGroup='$i'>$textboxText<br /></span>
<span LabelGroup='$i'>Test Text : </span>
<input type='text' customID='$guid'/>
<input type='button' Class='Button' ButtonGroup='$i' value='Button Text' /></br>
</script>
<!-- And here, some testing elements -->
​<input type="button" id="New" value="New Row">
<input type="text" id="MainContent_TextBox" value="Some Value">
<div id="MainContent_Panel1"></div>​​​​​​​
And then, in your javascript, you only need to get the html contents of the script tag, then replace each $variable with the value to use.
Please note that you should use /g when calling .replace, to replace all ocurrencies of your $variable in the template.
i = 1;
$("#New").click(NewRow);
function NewRow(){
var guid = jQuery.guid++;
var panel = $('#MainContent_Panel1');
var textboxText = $('#MainContent_TextBox').val();
var html = $("#template").html()
.replace(/\$i/g,i)
.replace(/\$guid/g,guid)
.replace(/\$textboxText/g,textboxText);
panel.append(html);
i++;
​}​
Using this approach, you are separating html from js code. Something that will help you in the future if you have to maintain this.
Hope it helps.
You could create your tags on the fly like this:
var $span1 = $("<span />").text("your text").attr("TextGroup", i);
...
var $text = $('<input type="text" />').attr("customID", guid);
...
var $button = $('<input type="button" />').addClass("Button").val("Button text").attr("ButtonGroup", i);
And then just add them to the control container
$panel.append($span1).append(...);
Try it live on Fiddler

How to incrementally reveal div tags

I have collection of div tags in the form tag, like this:
<form ...>
<div id="div1"> ... </div>
<div id="div2"> ... </div>
...
...
</form>
I want to display only div1 in the visible area than when user presses next, the next div tag i.e. div2 is displayed, and so on.
How can I achieve this?
I don't have much knowledge about different approaches available to do this, but I have some knowledge of Javascript, so any idea will be appreciated.
P.S. please provide sample code if possible, also I want client-side scripting.
Here's some javascript and html demonstration that may help. Increment a current integer. You could deincrement with -- for back as well. There are many ways to do this. This is just one I thought of.
<img src="mynextbutton.jpg" onclick="showNext()" />
<form ...>
<div id="Div0" style="display:inherit;"> ... </div>
<div id="Div1" style="display:none;"> ... </div>
<div id="Div2" style="display:none;"> ... </div>
...
...
</form>
//---------------------------------------------------
var currentDiv = 0;
function showNext()
{
document.getElementById("Div"+currentDiv).style.display = "none";
currentDiv ++;
document.getElementById("Div"+currentDiv).style.display = "ihherit";
}
If you put all of the element IDs into an array, and then use that to get the next item you can remove the dependence on the ID numbering determining the order that they rotate in, and also prevent them from needing to follow such a rigid format.
//add all element IDs to this array
var elements = ["firstElementID","div2","someConentsID","lastElementID"];
var currentIndex = 0;
//ensure that the first item is visible at the start.
function next()
{
//hide current item.
document.getElementById(elements[currentIndex]).Style = "display:none";
//move up the current index by one, wrapping so as to stay within array bounds.
currentIndex = (currentIndex + 1) % elements.length;
//show the new current item.
document.getElementById(elements[currentIndex]).Style = "display:inline";
}
You can adjust the show/hide code to use JQuery, or whatever other mechanism you want.

Categories