Can you keep changes made to HTML/CSS with jQuery? - javascript

I keep track of my comic book collection online using a mass amount of tables.
I color the table cells based on which ones I have vs. don't have.
I'm trying to make my life easier by adding some jQuery to my site that will allow me to simply "click" on the cell to change the color.
What I don't know how to do is make the change PERMANENT. It works fine an dandy (and I'm going to add more functionality to cycle through more colors), but when I refresh the page all the changes made to the page are lost.
Is there a way to make the changes permanent?? Adding a "save" button perhaps? Not sure how to achieve this.
Simple Example of what I'm doing:
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
$(document).ready(function() {
$('td').click(function() {
$(this).css('background-color', '#5f0');
});
});
</script>
<table>
<tr>
<td>#1</td>
<td>Comic Title</td>
<td>Collected Edition</td>
<td>Omnibus</td>
</tr>
</table>

You can do that using localstorage or server side storage.
When the user makes changes to the page, store the css properties with respect to an identifier for that field preferrably ID. In JSON format and stringify it before storing to the localstorage.
When the page refreshes or loads, In the onload event , check the localstorage if it has any data. If it's not null then retrieve the value using the key. let's say "personalization". Then use JSON.parse() to get the original JSON object.
Now loop through the json object and use the key as ID and the value as the css properties. To apply the changes.
Example:
var cssprop = { 'cellId' : { 'color': 'red'}}
If the above is the json you have constructed on click of the cells.
localStorage.setItem("personalize", JSON.stringify(cssprop));
now on window.onload()
$(function() {
// In case you are persisting data in the server, make ajax call to retrieve the data and then store it in localstorage.
if(localStorage.getItem("personalization") != null) {
var personalize= localStorage.getItem("personalization");
var cssprop = JSON.parse(personalize);
// you can iterage the object
// use $("#"+keyOfObject).css(// use value of object);
}
});

Related

Set and get value of input with jStorage

I'm using jStorage to store the value of an input, when I click the save button. Then I want to set the stored value as the current input value on page load. It ain't working too well though.
HTML
<input type='text' id='name'>
<div id="save">Save</div>
JS
$('#save').click(function() {
$.jStorage.set("key", $("#name").val());
});
var input_value = $.jStorage.get("key");
It's a little tangled up:
$.jStorage.set("key", $("#name").val());
var input_value = $.jStorage.get("key");
When you're passing a selector to jQuery you have to pass a valid string, not just the raw CSS selector syntax. That is, you've got to get the selector expression into JavaScript first, and you do that by creating a string constant.
edit — If you want your <input> to show the last-saved value when the page loads, you'd do something like this:
$(function() {
$('#name').val( $.jStorage.get("key") || "" );
});
Wrapping the activity in a $(function() { ... }) wrapper ensures that the code won't run until the <input> field has been seen and parsed by the browser, but still very soon after the user sees the page load (essentially immediately).
Adding the extra || "" bit after the jStorage call ensures that if the value is null or undefined the user won't see that. If there's no stored value, in other words, that'll have the input just be empty. You could put any other default value in there of course.

How to update ZK Grid values from jQuery

I have three Tabs and in each tab, I have a Grid.
The data for each Grid is coming from a database, so I am using rowRenderer to populate the Grids. The following code is common for all three Grids:
<grid id="myGrid1" width="950px" sizedByContent="true" rowRenderer="com.example.renderer.MyRowRenderer">
The rows are constructed from Doublebox objects. The data is populated successfully.
The Problem:
I need to handle multiple-cell editing on the client side. The editing is done via mouse-clicking on a particular cell and entering a value.
As example let's say that the user edits first cell on the first row and the value should be
propagated to all other cells on the same row and in all three Grids (so also the two Grids which the user currently does not see, because they are in tabpanes).
I am using jQuery to do this value propagation and it works OK.
I am passing the jQuery as follows:
doublebox.setWidgetListener(Events.ON_CHANGING, jQuerySelectors);
doublebox.setWidgetListener(Events.ON_CHANGE, jQuerySelectors);
This makes it possible to change the value in 1 cell and the change is instantly (visually) seen in all other cells filtered by jQuery selectors.
The problem is that the value is visually distributed to all the cells, but when I try to save the Grid data back to the database, the background values are the old ones.
I am assuming that ZK-Grid component is not aware that jQuery changed all the cell values. Nevertheless if I manually click on a cell that already has the NEW value (enter/leave/change focus) when I save the grid the NEW value is correct in that particular cell. Maybe that's a hint how can I resolve this.
Code of how I extract the Grid values:
Grid tGrid = (Grid) event.getTarget().getFellow("myGrid1");
ListModel model = tGrid.getModel();
MyCustomRow tRow = (MyCustomRow)model.getElementAt(i);
The model for my Grid is a List of MyCustomRow:
myGrid1.setModel(new ListModelList(List<MyCustomRow> populatedList));
I have a couple of assumptions, but whatever I have tried, hasn't worked. I have in mind that jQuery events and ZK-Events are different and probably isolated in different contexts. (Although I have tried to fire events from jQuery and so on..)
Do you have any suggestions? As a whole is my approach correct or there's another way to do this? Thanks for your time in advance!
Your problem is exactly what you are expecting.
Zk has it's own event system and do not care about your jq,
cos it's jq and zk don't observ the DOM.
The ways to solve your problem.
Use the "ZK-Way":
Simply listen at server-side and chage things there.
I am not sure if not selected Tabs
are updateable, but I am sure you could update the Grid
components on the select event of the Tab.
Fire an zk-event your self:
All you need to know, is written in the zk doc.
Basically, you collect your data at client side, send
an Event to the server via zAu.send() extract the
data from the json object at serverside and update your Grids
I would prefer the first one, cos it's less work and there should not be
a notable difference in traffic.
I post the solution we came up with:
This is the javascript attached to each Doublebox in the Z-Grid
//getting the value of the clicked cell
var currVal = jq(this).val();
//getting the next cell (on the right of the clicked cell)
objCells = jq(this).parents('td').next().find('.z-doublebox');
// if there's a next cell (returned array has length) - set the value and
// fire ZK onChange Event
if (objCells.length) {
zk.Widget.$(jq(objCells).attr('id')).setValue(currVal);
zk.Widget.$(jq(objCells).attr('id')).fireOnChange();
} else { //otherwise we assume this is the last cell of the current tab
//So we get the current row, because we want to edit the cells in the same row in the next tabs
var currRow = jq(this).parents('tr').prevAll().length;
//finding the next cell, on the same row in the hidden tab and applying the same logic
objCellsHiddenTabs = jq(this).parents('.z-tabpanel').next().find('.z-row:eq(' + currRow + ')').find('.z-doublebox');
if (objCellsHiddenTabs.length) {
zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).setValue(currVal);
zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).fireOnChange();
}
}
The java code in the RowRenderer class looks something like this:
...
if (someBean != null) {
binder.bindBean("tBean", someBean);
Doublebox box = new Doublebox();
setDefaultStyle(box);
row.appendChild(box);
binder.addBinding(box, "value", "tBean.someSetter");
...
private void setDefaultStyle(Doublebox box) {
box.setFormat("#.00");
box.setConstraint("no negative,no empty");
box.setWidth("50px");
String customJS = ""; //the JS above
//this is used to visually see that you're editing multiple cells at once
String customJSNoFireOnChange = "jq(this).parents('td').nextAll().find('.z-doublebox').val(jq(this).val());";
box.setWidgetListener(Events.ON_CHANGING, customJSNoFireOnChange);
box.setWidgetListener(Events.ON_CHANGE, customJS);
}
What is interesting to notice is that ZK optimizes this fireOnChange Events and send only 1 ajax request to the server containing the updates to the necessary cells.

Where and how to store data locally using $.post

I am using this code to edit data on table ,this is allowing me to edit data ,but I am not able to find that where and how should I store data locally on that form itself ,if i don't want to store it in database, I want to know what this "/somewhere" should be(url or some file or what).
<table id="mylist_remark"><tr>
<td class="editable" contenteditable="true">Something</td>
</tr></table>
$("#mylist_remark .editable").bind("blur", function(e) {
console.log($(e.target).text());
$.post("/somewhere", {remark: $(e.target).text(), candidate_id: $(e.target).nearest("tr").attr("id")}, function() { console.log("success"); });
});
... how should I store data locally on that form itself ,if i don't want to store it in database...
One solution would be to use localStorage to save the form elements locally.
If you felt like using jQuery, you could make the problem simple:
$("input").change(function(){
var input = $(this).val();
localStorage.setItem("input",input);
}
Then when the page loads, you set the val to the localStorage item:
var input = localStorage.getItem("input");
$("input").val(input)
More on localStorage, and even more on localStorage.

jQuery cleaning HTML table

This is my table:
<tr class=stuff>
<td id=id></td>
<td id=city_id></td>
<td id=temp></td>
<td id=date></td>
</tr>
This is my Javascript:
<script>
$(document).ready(function() { // waits when document is ready
$('.data').change(function() { // when dropbox value changes do this
getWeather(); // here I tried inserting table clearing code
});
});
function getWeather() {
$.getJSON('getTemperature/' + $('.data option:selected').val(), null, function(data) { // JSON request
$("#id").text(data.id); // changes fields accordingly
$("#city_id").text(data.city_id);
$("#temp").text(data.temperature);
$("#date").text(data.date);
});
}
</script>
Every item in dropdown menu does not have response from server, so I want it to clear the table just before making a new JSON request. So when JSON comes back with data, data is updated accordingly, but when JSON comes back with nothing, then all the tables will be empty.
At the moment when JSON retrieves no data, the old data still remains in the table.
I tried using $('.stuff').remove() and $('.stuff').clean() , but after using them right before getWeather(); then later I wasn't able to put info into table which I received from JSON. It just did not work anymore.
Feel free to ask any questions.
Try this
$('.stuff td').text("");
getWeather();
Depending how much of this sort of thing you will be doing on your site you might want to look into KnockoutJS, it is designed for dynamic displays with changing data, including auto hiding sections.

How to get values from dynamically added (using javascript) elements?

On my aspx page I dynamically create html controls on client side using javascript. For example, after page load you can click button in a browser, by clicking button html input and select elements appear. You may click once again, and this elements (input and select) will added again. So, you can create so many inputs and selects as you want (all this using javascript, no postbacks)
After user created some inputs and selects and entered some information in it, he posted form. I want on server side to find all this dynamically added elements and perform some actions depends on values in this controls.
How can I find dynamically added elements, and what is the best and elegant way to achieve this?
Thanks in advance.
In the Javascript that creates the new elements, increment a counter each time an element is created. Add the value of the counter to the name of the input element so each element has a unique name.
Add the final value of the counter to a hidden form field when the form is posted.
In your server side code, create a loop that starts at zero and continues until you have reached the value of the counter. Within the loop, fetch the posted value of the corresponding form field.
When you add the elements, assign unique IDs to them, and then retrieve their values using Request.Form["UniqueIdHere"] (C#) or Request.Form("UniqueIdHere") (VB.NET).
Create a loop that loops through each input and select object, that grabs the name/id of the current object and its corresponding value. Then add those items to an array and once the loop is completed, pass those values to your aspx file.
You can view an example with this approach at: http://jsfiddle.net/euHeX/. It currently just alerts the values, but you could easily modify it to pass the values as a parameter via ajax to your handler aspx file. The code will add new inputs or select boxes based off of the input provided. This would of course be modified to reflect your current setup.
HTML:
<div id="dynamic"></div>
<input type="button" id="submit-form" value="Submit>>">
JavaScript (using jQuery):
function createInput(type){
for(var i=0; i<5; i++){
if(type==0){
var obj = '<input type="text" id="'+i+'" class="dynamicContent">';
}else if(type==1){
var obj = '<select id="'+i+'" class="dynamicContent"><option>--Select--</option></select>';
}
$("#dynamic").append(obj);
}
}
function getContent(){
var inputArray = [];
$(".dynamicContent").each(function(k,v){
var o = $(this);
var oType;
if(o.is("input")){ oType = "input"; }
if(o.is("select")){ oType = "select"; }
var oID = oType+o.attr("id");
var oValue = o.val();
inputArray.push(oID+'='+oValue);
});
alert(inputArray);
}
$("#submit-form").click(function(){
getContent();
});
// Set type to 0 for input or 1 for select
var type = '1';
createInput(type);
If you're using jQuery you can use .live() to achive this like a peace of cake!
http://api.jquery.com/live/
I don't know if your controls will survive the postback the way you're creating them, but a good technique for accessing dynamically generated controls (assuming that you've figured out how to persist them) is to do something like the following:
Add a panel to your page. Add your dynamically created controls to this panel.
In the OnClick event handler (or other method), do something like the following:
foreach (DropDownList ddl in Panel1.Controls.OfType<DropDownList>())
{
//put code here
}
foreach (TextBox txt in Panel1.Controls.OfType<TextBox>())
{
//put code here
}

Categories

Resources